Merge "Enforce encapsulation for MarginLayoutParams startMargin and endMargin" into jb-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 1911647..db378c8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -555,6 +555,7 @@
     field public static final int indicatorRight = 16843022; // 0x101010e
     field public static final int inflatedId = 16842995; // 0x10100f3
     field public static final int initOrder = 16842778; // 0x101001a
+    field public static final int initialKeyguardLayout = 16843714; // 0x10103c2
     field public static final int initialLayout = 16843345; // 0x1010251
     field public static final int innerRadius = 16843359; // 0x101025f
     field public static final int innerRadiusRatio = 16843163; // 0x101019b
@@ -1120,6 +1121,8 @@
     field public static final int weekNumberColor = 16843589; // 0x1010345
     field public static final int weekSeparatorLineColor = 16843590; // 0x1010346
     field public static final int weightSum = 16843048; // 0x1010128
+    field public static final int widgetCategory = 16843716; // 0x10103c4
+    field public static final int widgetFeatures = 16843715; // 0x10103c3
     field public static final int widgetLayout = 16843243; // 0x10101eb
     field public static final int width = 16843097; // 0x1010159
     field public static final int windowActionBar = 16843469; // 0x10102cd
@@ -4399,6 +4402,7 @@
 
   public class AppWidgetManager {
     method public boolean bindAppWidgetIdIfAllowed(int, android.content.ComponentName);
+    method public boolean bindAppWidgetIdIfAllowed(int, android.content.ComponentName, android.os.Bundle);
     method public int[] getAppWidgetIds(android.content.ComponentName);
     method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo(int);
     method public android.os.Bundle getAppWidgetOptions(int);
@@ -4428,6 +4432,7 @@
     field public static final java.lang.String EXTRA_CUSTOM_INFO = "customInfo";
     field public static final int INVALID_APPWIDGET_ID = 0; // 0x0
     field public static final java.lang.String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
+    field public static final java.lang.String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
     field public static final java.lang.String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight";
     field public static final java.lang.String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth";
     field public static final java.lang.String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight";
@@ -4454,9 +4459,15 @@
     field public static final int RESIZE_HORIZONTAL = 1; // 0x1
     field public static final int RESIZE_NONE = 0; // 0x0
     field public static final int RESIZE_VERTICAL = 2; // 0x2
+    field public static final int WIDGET_CATEGORY_HOME_SCREEN = 1; // 0x1
+    field public static final int WIDGET_CATEGORY_KEYGUARD = 2; // 0x2
+    field public static final int WIDGET_FEATURES_CLOCK = 1; // 0x1
+    field public static final int WIDGET_FEATURES_NONE = 0; // 0x0
+    field public static final int WIDGET_FEATURES_STATUS = 2; // 0x2
     field public int autoAdvanceViewId;
     field public android.content.ComponentName configure;
     field public int icon;
+    field public int initialKeyguardLayout;
     field public int initialLayout;
     field public java.lang.String label;
     field public int minHeight;
@@ -4467,6 +4478,8 @@
     field public android.content.ComponentName provider;
     field public int resizeMode;
     field public int updatePeriodMillis;
+    field public int widgetCategory;
+    field public int widgetFeatures;
   }
 
 }
@@ -9865,6 +9878,7 @@
     field public static final java.lang.String SCENE_MODE_BEACH = "beach";
     field public static final java.lang.String SCENE_MODE_CANDLELIGHT = "candlelight";
     field public static final java.lang.String SCENE_MODE_FIREWORKS = "fireworks";
+    field public static final java.lang.String SCENE_MODE_HDR = "hdr";
     field public static final java.lang.String SCENE_MODE_LANDSCAPE = "landscape";
     field public static final java.lang.String SCENE_MODE_NIGHT = "night";
     field public static final java.lang.String SCENE_MODE_NIGHT_PORTRAIT = "night-portrait";
@@ -10217,6 +10231,7 @@
     method public final android.os.IBinder onBind(android.content.Intent);
     method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl onCreateInputMethodInterface();
     method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
+    method public boolean onGenericMotionEvent(android.view.MotionEvent);
     method public boolean onTrackballEvent(android.view.MotionEvent);
   }
 
@@ -10229,6 +10244,7 @@
 
   public abstract class AbstractInputMethodService.AbstractInputMethodSessionImpl implements android.view.inputmethod.InputMethodSession {
     ctor public AbstractInputMethodService.AbstractInputMethodSessionImpl();
+    method public void dispatchGenericMotionEvent(int, android.view.MotionEvent, android.view.inputmethod.InputMethodSession.EventCallback);
     method public void dispatchKeyEvent(int, android.view.KeyEvent, android.view.inputmethod.InputMethodSession.EventCallback);
     method public void dispatchTrackballEvent(int, android.view.MotionEvent, android.view.inputmethod.InputMethodSession.EventCallback);
     method public boolean isEnabled();
@@ -26697,6 +26713,7 @@
 
   public abstract interface InputMethodSession {
     method public abstract void appPrivateCommand(java.lang.String, android.os.Bundle);
+    method public abstract void dispatchGenericMotionEvent(int, android.view.MotionEvent, android.view.inputmethod.InputMethodSession.EventCallback);
     method public abstract void dispatchKeyEvent(int, android.view.KeyEvent, android.view.inputmethod.InputMethodSession.EventCallback);
     method public abstract void dispatchTrackballEvent(int, android.view.MotionEvent, android.view.inputmethod.InputMethodSession.EventCallback);
     method public abstract void displayCompletions(android.view.inputmethod.CompletionInfo[]);
@@ -26926,6 +26943,9 @@
     method public boolean useHttpAuthUsernamePassword();
   }
 
+  public abstract class JavascriptInterface implements java.lang.annotation.Annotation {
+  }
+
   public class JsPromptResult extends android.webkit.JsResult {
     method public void confirm(java.lang.String);
   }
@@ -27050,7 +27070,7 @@
   }
 
   public abstract class WebSettings {
-    method public boolean enableSmoothTransition();
+    method public deprecated boolean enableSmoothTransition();
     method public boolean getAllowContentAccess();
     method public boolean getAllowFileAccess();
     method public abstract boolean getAllowFileAccessFromFileURLs();
@@ -27116,7 +27136,7 @@
     method public void setDefaultZoom(android.webkit.WebSettings.ZoomDensity);
     method public void setDisplayZoomControls(boolean);
     method public synchronized void setDomStorageEnabled(boolean);
-    method public void setEnableSmoothTransition(boolean);
+    method public deprecated void setEnableSmoothTransition(boolean);
     method public synchronized void setFantasyFontFamily(java.lang.String);
     method public synchronized void setFixedFontFamily(java.lang.String);
     method public synchronized void setGeolocationDatabasePath(java.lang.String);
@@ -27155,7 +27175,7 @@
     field public static final int LOAD_CACHE_ELSE_NETWORK = 1; // 0x1
     field public static final int LOAD_CACHE_ONLY = 3; // 0x3
     field public static final int LOAD_DEFAULT = -1; // 0xffffffff
-    field public static final int LOAD_NORMAL = 0; // 0x0
+    field public static final deprecated int LOAD_NORMAL = 0; // 0x0
     field public static final int LOAD_NO_CACHE = 2; // 0x2
   }
 
@@ -27238,13 +27258,13 @@
     ctor public WebView(android.content.Context);
     ctor public WebView(android.content.Context, android.util.AttributeSet);
     ctor public WebView(android.content.Context, android.util.AttributeSet, int);
-    ctor public WebView(android.content.Context, android.util.AttributeSet, int, boolean);
+    ctor public deprecated WebView(android.content.Context, android.util.AttributeSet, int, boolean);
     method public void addJavascriptInterface(java.lang.Object, java.lang.String);
     method public boolean canGoBack();
     method public boolean canGoBackOrForward(int);
     method public boolean canGoForward();
-    method public boolean canZoomIn();
-    method public boolean canZoomOut();
+    method public deprecated boolean canZoomIn();
+    method public deprecated boolean canZoomOut();
     method public android.graphics.Picture capturePicture();
     method public void clearCache(boolean);
     method public void clearFormData();
@@ -27272,7 +27292,7 @@
     method public java.lang.String[] getHttpAuthUsernamePassword(java.lang.String, java.lang.String);
     method public java.lang.String getOriginalUrl();
     method public int getProgress();
-    method public float getScale();
+    method public deprecated float getScale();
     method public android.webkit.WebSettings getSettings();
     method public java.lang.String getTitle();
     method public java.lang.String getUrl();
@@ -27309,13 +27329,13 @@
     method public android.webkit.WebBackForwardList saveState(android.os.Bundle);
     method public void saveWebArchive(java.lang.String);
     method public void saveWebArchive(java.lang.String, boolean, android.webkit.ValueCallback<java.lang.String>);
-    method public void setCertificate(android.net.http.SslCertificate);
+    method public deprecated void setCertificate(android.net.http.SslCertificate);
     method public void setDownloadListener(android.webkit.DownloadListener);
     method public void setFindListener(android.webkit.WebView.FindListener);
     method public void setHorizontalScrollbarOverlay(boolean);
     method public void setHttpAuthUsernamePassword(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
     method public void setInitialScale(int);
-    method public void setMapTrackballToArrowKeys(boolean);
+    method public deprecated void setMapTrackballToArrowKeys(boolean);
     method public void setNetworkAvailable(boolean);
     method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
     method public void setVerticalScrollbarOverlay(boolean);
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index bb108c8..bc9e74e 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -63,7 +63,7 @@
     private boolean mStopOption = false;
 
     private int mRepeat = 0;
-    private int mUserId = 0;
+    private int mUserId;
 
     private String mProfileFile;
 
@@ -160,7 +160,7 @@
         return userId;
     }
 
-    private Intent makeIntent() throws URISyntaxException {
+    private Intent makeIntent(int defUser) throws URISyntaxException {
         Intent intent = new Intent();
         Intent baseIntent = intent;
         boolean hasIntentInfo = false;
@@ -170,7 +170,7 @@
         mStopOption = false;
         mRepeat = 0;
         mProfileFile = null;
-        mUserId = 0;
+        mUserId = defUser;
         Uri data = null;
         String type = null;
 
@@ -404,7 +404,7 @@
     }
 
     private void runStartService() throws Exception {
-        Intent intent = makeIntent();
+        Intent intent = makeIntent(UserHandle.USER_CURRENT);
         if (mUserId == UserHandle.USER_ALL) {
             System.err.println("Error: Can't start activity with user 'all'");
             return;
@@ -417,7 +417,7 @@
     }
 
     private void runStart() throws Exception {
-        Intent intent = makeIntent();
+        Intent intent = makeIntent(UserHandle.USER_CURRENT);
 
         if (mUserId == UserHandle.USER_ALL) {
             System.err.println("Error: Can't start service with user 'all'");
@@ -456,7 +456,7 @@
                     packageName = activities.get(0).activityInfo.packageName;
                 }
                 System.out.println("Stopping: " + packageName);
-                mAm.forceStopPackage(packageName);
+                mAm.forceStopPackage(packageName, mUserId);
                 Thread.sleep(250);
             }
     
@@ -570,11 +570,33 @@
     }
 
     private void runForceStop() throws Exception {
-        mAm.forceStopPackage(nextArgRequired());
+        int userId = UserHandle.USER_ALL;
+
+        String opt;
+        while ((opt=nextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = parseUserArg(nextArgRequired());
+            } else {
+                System.err.println("Error: Unknown option: " + opt);
+                return;
+            }
+        }
+        mAm.forceStopPackage(nextArgRequired(), userId);
     }
 
     private void runKill() throws Exception {
-        mAm.killBackgroundProcesses(nextArgRequired());
+        int userId = UserHandle.USER_ALL;
+
+        String opt;
+        while ((opt=nextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = parseUserArg(nextArgRequired());
+            } else {
+                System.err.println("Error: Unknown option: " + opt);
+                return;
+            }
+        }
+        mAm.killBackgroundProcesses(nextArgRequired(), userId);
     }
 
     private void runKillAll() throws Exception {
@@ -582,7 +604,7 @@
     }
 
     private void sendBroadcast() throws Exception {
-        Intent intent = makeIntent();
+        Intent intent = makeIntent(UserHandle.USER_ALL);
         IntentReceiver receiver = new IntentReceiver();
         System.out.println("Broadcasting: " + intent);
         mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false,
@@ -595,7 +617,7 @@
         boolean wait = false;
         boolean rawMode = false;
         boolean no_window_animation = false;
-        int userId = 0;
+        int userId = UserHandle.USER_CURRENT;
         Bundle args = new Bundle();
         String argKey = null, argValue = null;
         IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
@@ -672,17 +694,37 @@
         String profileFile = null;
         boolean start = false;
         boolean wall = false;
+        int userId = UserHandle.USER_CURRENT;
         int profileType = 0;
-        
+
         String process = null;
-        
+
         String cmd = nextArgRequired();
 
         if ("start".equals(cmd)) {
             start = true;
-            wall = "--wall".equals(nextOption());
+            String opt;
+            while ((opt=nextOption()) != null) {
+                if (opt.equals("--user")) {
+                    userId = parseUserArg(nextArgRequired());
+                } else if (opt.equals("--wall")) {
+                    wall = true;
+                } else {
+                    System.err.println("Error: Unknown option: " + opt);
+                    return;
+                }
+            }
             process = nextArgRequired();
         } else if ("stop".equals(cmd)) {
+            String opt;
+            while ((opt=nextOption()) != null) {
+                if (opt.equals("--user")) {
+                    userId = parseUserArg(nextArgRequired());
+                } else {
+                    System.err.println("Error: Unknown option: " + opt);
+                    return;
+                }
+            }
             process = nextArg();
         } else {
             // Compatibility with old syntax: process is specified first.
@@ -694,7 +736,12 @@
                 throw new IllegalArgumentException("Profile command " + process + " not valid");
             }
         }
-        
+
+        if (userId == UserHandle.USER_ALL) {
+            System.err.println("Error: Can't profile with user 'all'");
+            return;
+        }
+
         ParcelFileDescriptor fd = null;
 
         if (start) {
@@ -722,7 +769,7 @@
             } else if (start) {
                 //removeWallOption();
             }
-            if (!mAm.profileControl(process, start, profileFile, fd, profileType)) {
+            if (!mAm.profileControl(process, userId, start, profileFile, fd, profileType)) {
                 wall = false;
                 throw new AndroidException("PROFILE FAILED on process " + process);
             }
@@ -734,7 +781,24 @@
     }
 
     private void runDumpHeap() throws Exception {
-        boolean managed = !"-n".equals(nextOption());
+        boolean managed = true;
+        int userId = UserHandle.USER_CURRENT;
+
+        String opt;
+        while ((opt=nextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = parseUserArg(nextArgRequired());
+                if (userId == UserHandle.USER_ALL) {
+                    System.err.println("Error: Can't dump heap with user 'all'");
+                    return;
+                }
+            } else if (opt.equals("-n")) {
+                managed = false;
+            } else {
+                System.err.println("Error: Unknown option: " + opt);
+                return;
+            }
+        }
         String process = nextArgRequired();
         String heapFile = nextArgRequired();
         ParcelFileDescriptor fd = null;
@@ -750,7 +814,7 @@
             return;
         }
 
-        if (!mAm.dumpHeap(process, managed, heapFile, fd)) {
+        if (!mAm.dumpHeap(process, userId, managed, heapFile, fd)) {
             throw new AndroidException("HEAP DUMP FAILED on process " + process);
         }
     }
@@ -1123,32 +1187,26 @@
 
     private void runDisplaySize() throws Exception {
         String size = nextArgRequired();
-        int m, n;
+        int w, h;
         if ("reset".equals(size)) {
-            m = n = -1;
+            w = h = -1;
         } else {
             int div = size.indexOf('x');
             if (div <= 0 || div >= (size.length()-1)) {
                 System.err.println("Error: bad size " + size);
                 return;
             }
-            String mstr = size.substring(0, div);
-            String nstr = size.substring(div+1);
+            String wstr = size.substring(0, div);
+            String hstr = size.substring(div+1);
             try {
-                m = Integer.parseInt(mstr);
-                n = Integer.parseInt(nstr);
+                w = Integer.parseInt(wstr);
+                h = Integer.parseInt(hstr);
             } catch (NumberFormatException e) {
                 System.err.println("Error: bad number " + e);
                 return;
             }
         }
 
-        if (m < n) {
-            int tmp = m;
-            m = n;
-            n = tmp;
-        }
-
         IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
                 Context.WINDOW_SERVICE));
         if (wm == null) {
@@ -1157,9 +1215,9 @@
         }
 
         try {
-            if (m >= 0 && n >= 0) {
+            if (w >= 0 && h >= 0) {
                 // TODO(multidisplay): For now Configuration only applies to main screen.
-                wm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, m, n);
+                wm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h);
             } else {
                 wm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY);
             }
@@ -1204,7 +1262,7 @@
     }
 
     private void runToUri(boolean intentScheme) throws Exception {
-        Intent intent = makeIntent();
+        Intent intent = makeIntent(UserHandle.USER_CURRENT);
         System.out.println(intent.toUri(intentScheme ? Intent.URI_INTENT_SCHEME : 0));
     }
 
@@ -1363,23 +1421,24 @@
         System.err.println(
                 "usage: am [subcommand] [options]\n" +
                 "usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
-                "               [--R COUNT] [-S] [--opengl-trace] <INTENT>\n" +
-                "       am startservice <INTENT>\n" +
-                "       am force-stop <PACKAGE>\n" +
-                "       am kill <PACKAGE>\n" +
+                "               [--R COUNT] [-S] [--opengl-trace]\n" +
+                "               [--user <USER_ID> | current] <INTENT>\n" +
+                "       am startservice [--user <USER_ID> | current] <INTENT>\n" +
+                "       am force-stop [--user <USER_ID> | all | current] <PACKAGE>\n" +
+                "       am kill [--user <USER_ID> | all | current] <PACKAGE>\n" +
                 "       am kill-all\n" +
-                "       am broadcast <INTENT>\n" +
+                "       am broadcast [--user <USER_ID> | all | current] <INTENT>\n" +
                 "       am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
-                "               [--user <USER_ID> | all | current]\n" +
+                "               [--user <USER_ID> | current]\n" +
                 "               [--no-window-animation] <COMPONENT>\n" +
-                "       am profile start <PROCESS> <FILE>\n" +
-                "       am profile stop [<PROCESS>]\n" +
-                "       am dumpheap [flags] <PROCESS> <FILE>\n" +
+                "       am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" +
+                "       am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
+                "       am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
                 "       am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
                 "       am clear-debug-app\n" +
                 "       am monitor [--gdb <port>]\n" +
                 "       am screen-compat [on|off] <PACKAGE>\n" +
-                "       am display-size [reset|MxN]\n" +
+                "       am display-size [reset|WxH]\n" +
                 "       am display-density [reset|DENSITY]\n" +
                 "       am to-uri [INTENT]\n" +
                 "       am to-intent-uri [INTENT]\n" +
@@ -1395,18 +1454,28 @@
                 "        the top activity will be finished.\n" +
                 "    -S: force stop the target app before starting the activity\n" +
                 "    --opengl-trace: enable tracing of OpenGL functions\n" +
+                "    --user <USER_ID> | current: Specify which user to run as; if not\n" +
+                "        specified then run as the current user.\n" +
                 "\n" +
-                "am startservice: start a Service.\n" +
+                "am startservice: start a Service.  Options are:\n" +
+                "    --user <USER_ID> | current: Specify which user to run as; if not\n" +
+                "        specified then run as the current user.\n" +
                 "\n" +
                 "am force-stop: force stop everything associated with <PACKAGE>.\n" +
+                "    --user <USER_ID> | all | current: Specify user to force stop;\n" +
+                "        all users if not specified.\n" +
                 "\n" +
                 "am kill: Kill all processes associated with <PACKAGE>.  Only kills.\n" +
                 "  processes that are safe to kill -- that is, will not impact the user\n" +
                 "  experience.\n" +
+                "    --user <USER_ID> | all | current: Specify user whose processes to kill;\n" +
+                "        all users if not specified.\n" +
                 "\n" +
                 "am kill-all: Kill all background processes.\n" +
                 "\n" +
-                "am broadcast: send a broadcast Intent.\n" +
+                "am broadcast: send a broadcast Intent.  Options are:\n" +
+                "    --user <USER_ID> | all | current: Specify which user to send to; if not\n" +
+                "        specified then send to all users.\n" +
                 "\n" +
                 "am instrument: start an Instrumentation.  Typically this target <COMPONENT>\n" +
                 "  is the form <TEST_PACKAGE>/<RUNNER_CLASS>.  Options are:\n" +
@@ -1417,13 +1486,20 @@
                 "    -p <FILE>: write profiling data to <FILE>\n" +
                 "    -w: wait for instrumentation to finish before returning.  Required for\n" +
                 "        test runners.\n" +
-                "    --user [<USER_ID> | all | current]: Specify user instrumentation runs in.\n" +
+                "    --user <USER_ID> | current: Specify user instrumentation runs in;\n" +
+                "        current user if not specified.\n" +
                 "    --no-window-animation: turn off window animations will running.\n" +
                 "\n" +
-                "am profile: start and stop profiler on a process.\n" +
+                "am profile: start and stop profiler on a process.  The given <PROCESS> argument\n" +
+                "  may be either a process name or pid.  Options are:\n" +
+                "    --user <USER_ID> | current: When supplying a process name,\n" +
+                "        specify user of process to profile; uses current user if not specified.\n" +
                 "\n" +
-                "am dumpheap: dump the heap of a process.  Options are:\n" +
+                "am dumpheap: dump the heap of a process.  The given <PROCESS> argument may\n" +
+                "  be either a process name or pid.  Options are:\n" +
                 "    -n: dump native heap instead of managed heap\n" +
+                "    --user <USER_ID> | current: When supplying a process name,\n" +
+                "        specify user of process to dump; uses current user if not specified.\n" +
                 "\n" +
                 "am set-debug-app: set application <PACKAGE> to debug.  Options are:\n" +
                 "    -w: wait for debugger when application starts\n" +
@@ -1444,10 +1520,10 @@
                 "\n" +
                 "am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
                 "\n" +
-                "am switch-user: switch to put USER_ID in the foreground, starting" +
+                "am switch-user: switch to put USER_ID in the foreground, starting\n" +
                 "  execution of that user if it is currently stopped.\n" +
                 "\n" +
-                "am stop-user: stop execution of USER_ID, not allowing it to run any" +
+                "am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
                 "  code until a later explicit switch to it.\n" +
                 "\n" +
                 "<INTENT> specifications include these flags and arguments:\n" +
@@ -1465,7 +1541,6 @@
                 "    [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
                 "    [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
                 "    [-n <COMPONENT>] [-f <FLAGS>]\n" +
-                "    [--user [<USER_ID> | all | current]\n" +
                 "    [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
                 "    [--debug-log-resolution] [--exclude-stopped-packages]\n" +
                 "    [--include-stopped-packages]\n" +
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index 341f30f..a21df0d 100755
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -66,15 +66,54 @@
                 }
             } else if (command.equals("tap")) {
                 if (args.length == 3) {
-                    sendTap(Float.parseFloat(args[1]), Float.parseFloat(args[2]));
+                    sendTap(InputDevice.SOURCE_TOUCHSCREEN, Float.parseFloat(args[1]), Float.parseFloat(args[2]));
                     return;
                 }
             } else if (command.equals("swipe")) {
                 if (args.length == 5) {
-                    sendSwipe(Float.parseFloat(args[1]), Float.parseFloat(args[2]),
+                    sendSwipe(InputDevice.SOURCE_TOUCHSCREEN, Float.parseFloat(args[1]), Float.parseFloat(args[2]),
                             Float.parseFloat(args[3]), Float.parseFloat(args[4]));
                     return;
                 }
+            } else if (command.equals("touchscreen") || command.equals("touchpad")) {
+                // determine input source
+                int inputSource = InputDevice.SOURCE_TOUCHSCREEN;
+                if (command.equals("touchpad")) {
+                    inputSource = InputDevice.SOURCE_TOUCHPAD;
+                }
+                // determine subcommand
+                if (args.length > 1) {
+                    String subcommand = args[1];
+                    if (subcommand.equals("tap")) {
+                        if (args.length == 4) {
+                            sendTap(inputSource, Float.parseFloat(args[2]),
+                                    Float.parseFloat(args[3]));
+                            return;
+                        }
+                    } else if (subcommand.equals("swipe")) {
+                        if (args.length == 6) {
+                            sendSwipe(inputSource, Float.parseFloat(args[2]),
+                                    Float.parseFloat(args[3]), Float.parseFloat(args[4]),
+                                    Float.parseFloat(args[5]));
+                            return;
+                        }
+                    }
+                }
+            } else if (command.equals("trackball")) {
+                // determine subcommand
+                if (args.length > 1) {
+                    String subcommand = args[1];
+                    if (subcommand.equals("press")) {
+                        sendTap(InputDevice.SOURCE_TRACKBALL, 0.0f, 0.0f);
+                        return;
+                    } else if (subcommand.equals("roll")) {
+                        if (args.length == 4) {
+                            sendMove(InputDevice.SOURCE_TRACKBALL, Float.parseFloat(args[2]),
+                                    Float.parseFloat(args[3]));
+                            return;
+                        }
+                    }
+                }
             } else {
                 System.err.println("Error: Unknown command: " + command);
                 showUsage();
@@ -127,33 +166,64 @@
                 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
     }
 
-    private void sendTap(float x, float y) {
+    private void sendTap(int inputSource, float x, float y) {
         long now = SystemClock.uptimeMillis();
-        injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x, y, 0));
-        injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, x, y, 0));
+        injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, x, y, 1.0f);
+        injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x, y, 0.0f);
     }
 
-    private void sendSwipe(float x1, float y1, float x2, float y2) {
+    private void sendSwipe(int inputSource, float x1, float y1, float x2, float y2) {
         final int NUM_STEPS = 11;
         long now = SystemClock.uptimeMillis();
-        injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x1, y1, 0));
+        injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, x1, y1, 1.0f);
         for (int i = 1; i < NUM_STEPS; i++) {
-            float alpha = (float)i / NUM_STEPS;
-            injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_MOVE,
-                    lerp(x1, x2, alpha), lerp(y1, y2, alpha), 0));
+            float alpha = (float) i / NUM_STEPS;
+            injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, lerp(x1, x2, alpha),
+                    lerp(y1, y2, alpha), 1.0f);
         }
-        injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, x2, y2, 0));
+        injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x1, y1, 0.0f);
+    }
+
+    /**
+     * Sends a simple zero-pressure move event.
+     *
+     * @param inputSource the InputDevice.SOURCE_* sending the input event
+     * @param dx change in x coordinate due to move
+     * @param dy change in y coordinate due to move
+     */
+    private void sendMove(int inputSource, float dx, float dy) {
+        long now = SystemClock.uptimeMillis();
+        injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, dx, dy, 0.0f);
     }
 
     private void injectKeyEvent(KeyEvent event) {
-        Log.i(TAG, "InjectKeyEvent: " + event);
+        Log.i(TAG, "injectKeyEvent: " + event);
         InputManager.getInstance().injectInputEvent(event,
                 InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
     }
 
-    private void injectPointerEvent(MotionEvent event) {
-        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
-        Log.i("Input", "InjectPointerEvent: " + event);
+    /**
+     * Builds a MotionEvent and injects it into the event stream.
+     *
+     * @param inputSource the InputDevice.SOURCE_* sending the input event
+     * @param action the MotionEvent.ACTION_* for the event
+     * @param when the value of SystemClock.uptimeMillis() at which the event happened
+     * @param x x coordinate of event
+     * @param y y coordinate of event
+     * @param pressure pressure of event
+     */
+    private void injectMotionEvent(int inputSource, int action, long when, float x, float y, float pressure) {
+        final float DEFAULT_SIZE = 1.0f;
+        final int DEFAULT_META_STATE = 0;
+        final float DEFAULT_PRECISION_X = 1.0f;
+        final float DEFAULT_PRECISION_Y = 1.0f;
+        final int DEFAULT_DEVICE_ID = 0;
+        final int DEFAULT_EDGE_FLAGS = 0;
+        MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure, DEFAULT_SIZE,
+                DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEFAULT_DEVICE_ID,
+                DEFAULT_EDGE_FLAGS);
+        event.setSource(inputSource);
+        Log.i("Input", "injectMotionEvent: " + event);
         InputManager.getInstance().injectInputEvent(event,
                 InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
     }
@@ -166,7 +236,9 @@
         System.err.println("usage: input ...");
         System.err.println("       input text <string>");
         System.err.println("       input keyevent <key code number or name>");
-        System.err.println("       input tap <x> <y>");
-        System.err.println("       input swipe <x1> <y1> <x2> <y2>");
+        System.err.println("       input [touchscreen|touchpad] tap <x> <y>");
+        System.err.println("       input [touchscreen|touchpad] swipe <x1> <y1> <x2> <y2>");
+        System.err.println("       input trackball press");
+        System.err.println("       input trackball roll <dx> <dy>");
     }
 }
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 68f8400..2934261 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -27,13 +27,15 @@
 dir_rec_t android_asec_dir;
 dir_rec_t android_app_dir;
 dir_rec_t android_app_private_dir;
+dir_rec_t android_app_lib_dir;
 dir_rec_t android_media_dir;
 dir_rec_array_t android_system_dirs;
 
 int install(const char *pkgname, uid_t uid, gid_t gid)
 {
     char pkgdir[PKG_PATH_MAX];
-    char libdir[PKG_PATH_MAX];
+    char libsymlink[PKG_PATH_MAX];
+    char applibdir[PKG_PATH_MAX];
 
     if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
         ALOGE("invalid uid/gid: %d %d\n", uid, gid);
@@ -45,64 +47,49 @@
         return -1;
     }
 
-    if (create_pkg_path(libdir, pkgname, PKG_LIB_POSTFIX, 0)) {
-        ALOGE("cannot create package lib path\n");
+    if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, 0)) {
+        ALOGE("cannot create package lib symlink origin path\n");
+        return -1;
+    }
+
+    if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
+        ALOGE("cannot create package lib symlink dest path\n");
         return -1;
     }
 
     if (mkdir(pkgdir, 0751) < 0) {
         ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
-        return -errno;
+        return -1;
     }
     if (chmod(pkgdir, 0751) < 0) {
         ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
         unlink(pkgdir);
-        return -errno;
+        return -1;
     }
 
-    if (mkdir(libdir, 0755) < 0) {
-        ALOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
+    if (symlink(applibdir, libsymlink) < 0) {
+        ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, applibdir,
+                strerror(errno));
         unlink(pkgdir);
-        return -errno;
-    }
-    if (chmod(libdir, 0755) < 0) {
-        ALOGE("cannot chmod dir '%s': %s\n", libdir, strerror(errno));
-        unlink(libdir);
-        unlink(pkgdir);
-        return -errno;
-    }
-    if (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
-        ALOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
-        unlink(libdir);
-        unlink(pkgdir);
-        return -errno;
-    }
-
-#ifdef HAVE_SELINUX
-    if (selinux_android_setfilecon(libdir, pkgname, AID_SYSTEM) < 0) {
-        ALOGE("cannot setfilecon dir '%s': %s\n", libdir, strerror(errno));
-        unlink(libdir);
-        unlink(pkgdir);
-        return -errno;
-    }
-#endif
-
-    if (chown(pkgdir, uid, gid) < 0) {
-        ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(libdir);
-        unlink(pkgdir);
-        return -errno;
+        return -1;
     }
 
 #ifdef HAVE_SELINUX
     if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
         ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(libdir);
+        unlink(libsymlink);
         unlink(pkgdir);
-        return -errno;
+        return -1;
     }
 #endif
 
+    if (chown(pkgdir, uid, gid) < 0) {
+        ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(libsymlink);
+        unlink(pkgdir);
+        return -1;
+    }
+
     return 0;
 }
 
@@ -185,7 +172,6 @@
 int make_user_data(const char *pkgname, uid_t uid, uid_t persona)
 {
     char pkgdir[PKG_PATH_MAX];
-    char real_libdir[PKG_PATH_MAX];
 
     // Create the data dir for the package
     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona)) {
@@ -1038,85 +1024,3 @@
 
     return rc;
 }
-
-int unlinklib(const char* dataDir)
-{
-    char libdir[PKG_PATH_MAX];
-    struct stat s, libStat;
-    int rc = 0;
-
-    const size_t libdirLen = strlen(dataDir) + strlen(PKG_LIB_POSTFIX);
-    if (libdirLen >= PKG_PATH_MAX) {
-        return -1;
-    }
-
-    if (snprintf(libdir, sizeof(libdir), "%s%s", dataDir, PKG_LIB_POSTFIX) != (ssize_t)libdirLen) {
-        ALOGE("library dir not written successfully: %s\n", strerror(errno));
-        return -1;
-    }
-
-    if (stat(dataDir, &s) < 0) {
-        ALOGE("couldn't state data dir");
-        return -1;
-    }
-
-    if (chown(dataDir, AID_INSTALL, AID_INSTALL) < 0) {
-        ALOGE("failed to chown '%s': %s\n", dataDir, strerror(errno));
-        return -1;
-    }
-
-    if (chmod(dataDir, 0700) < 0) {
-        ALOGE("unlinklib() 1: failed to chmod '%s': %s\n", dataDir, strerror(errno));
-        rc = -1;
-        goto out;
-    }
-
-    if (lstat(libdir, &libStat) < 0) {
-        ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
-        rc = -1;
-        goto out;
-    }
-
-    if (S_ISDIR(libStat.st_mode)) {
-        if (delete_dir_contents(libdir, 1, 0) < 0) {
-            rc = -1;
-            goto out;
-        }
-    } else if (S_ISLNK(libStat.st_mode)) {
-        if (unlink(libdir) < 0) {
-            rc = -1;
-            goto out;
-        }
-    }
-
-    if (mkdir(libdir, 0755) < 0) {
-        ALOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
-        rc = -errno;
-        goto out;
-    }
-    if (chmod(libdir, 0755) < 0) {
-        ALOGE("cannot chmod dir '%s': %s\n", libdir, strerror(errno));
-        unlink(libdir);
-        rc = -errno;
-        goto out;
-    }
-    if (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
-        ALOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
-        unlink(libdir);
-        rc = -errno;
-        goto out;
-    }
-
-out:
-    if (chmod(dataDir, s.st_mode) < 0) {
-        ALOGE("unlinklib() 2: failed to chmod '%s': %s\n", dataDir, strerror(errno));
-        rc = -1;
-    }
-
-    if (chown(dataDir, s.st_uid, s.st_gid) < 0) {
-        ALOGE("failed to chown '%s' : %s\n", dataDir, strerror(errno));
-        return -1;
-    }
-
-    return rc;
-}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index cc8f014..a099537 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -126,11 +126,6 @@
     return linklib(arg[0], arg[1]);
 }
 
-static int do_unlinklib(char **arg, char reply[REPLY_MAX])
-{
-    return unlinklib(arg[0]);
-}
-
 struct cmdinfo {
     const char *name;
     unsigned numargs;
@@ -152,7 +147,6 @@
     { "rmuserdata",           2, do_rm_user_data },
     { "movefiles",            0, do_movefiles },
     { "linklib",              2, do_linklib },
-    { "unlinklib",            1, do_unlinklib },
     { "mkuserdata",           3, do_mk_user_data },
     { "rmuser",               1, do_rm_user },
     { "cloneuserdata",        3, do_clone_user_data },
@@ -290,6 +284,11 @@
         return -1;
     }
 
+    // Get the android app native library directory.
+    if (copy_and_append(&android_app_lib_dir, &android_data_dir, APP_LIB_SUBDIR) < 0) {
+        return -1;
+    }
+
     // Get the sd-card ASEC mount point.
     if (get_path_from_env(&android_asec_dir, "ASEC_MOUNTPOINT") < 0) {
         return -1;
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 5b81d2c..a229b970 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -62,6 +62,8 @@
 
 #define APP_SUBDIR             "app/" // sub-directory under ANDROID_DATA
 
+#define APP_LIB_SUBDIR         "app-lib/" // sub-directory under ANDROID_DATA
+
 #define MEDIA_SUBDIR           "media/" // sub-directory under ANDROID_DATA
 
 /* other handy constants */
@@ -93,6 +95,7 @@
 
 extern dir_rec_t android_app_dir;
 extern dir_rec_t android_app_private_dir;
+extern dir_rec_t android_app_lib_dir;
 extern dir_rec_t android_data_dir;
 extern dir_rec_t android_asec_dir;
 extern dir_rec_t android_media_dir;
@@ -207,4 +210,3 @@
 int dexopt(const char *apk_path, uid_t uid, int is_public);
 int movefiles();
 int linklib(const char* target, const char* source);
-int unlinklib(const char* libPath);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index bb3c56a..06f79e7 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1693,7 +1693,8 @@
      */
     public void killBackgroundProcesses(String packageName) {
         try {
-            ActivityManagerNative.getDefault().killBackgroundProcesses(packageName);
+            ActivityManagerNative.getDefault().killBackgroundProcesses(packageName,
+                    UserHandle.myUserId());
         } catch (RemoteException e) {
         }
     }
@@ -1718,7 +1719,8 @@
      */
     public void forceStopPackage(String packageName) {
         try {
-            ActivityManagerNative.getDefault().forceStopPackage(packageName);
+            ActivityManagerNative.getDefault().forceStopPackage(packageName,
+                    UserHandle.myUserId());
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index e5dd7b1..bf77f6e 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1214,7 +1214,8 @@
         case KILL_BACKGROUND_PROCESSES_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String packageName = data.readString();
-            killBackgroundProcesses(packageName);
+            int userId = data.readInt();
+            killBackgroundProcesses(packageName, userId);
             reply.writeNoException();
             return true;
         }
@@ -1229,7 +1230,8 @@
         case FORCE_STOP_PACKAGE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String packageName = data.readString();
-            forceStopPackage(packageName);
+            int userId = data.readInt();
+            forceStopPackage(packageName, userId);
             reply.writeNoException();
             return true;
         }
@@ -1255,12 +1257,13 @@
         case PROFILE_CONTROL_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String process = data.readString();
+            int userId = data.readInt();
             boolean start = data.readInt() != 0;
             int profileType = data.readInt();
             String path = data.readString();
             ParcelFileDescriptor fd = data.readInt() != 0
                     ? data.readFileDescriptor() : null;
-            boolean res = profileControl(process, start, path, fd, profileType);
+            boolean res = profileControl(process, userId, start, path, fd, profileType);
             reply.writeNoException();
             reply.writeInt(res ? 1 : 0);
             return true;
@@ -1484,9 +1487,10 @@
             String process = data.readString();
             boolean managed = data.readInt() != 0;
             String path = data.readString();
+            int userId = data.readInt();
             ParcelFileDescriptor fd = data.readInt() != 0
                     ? data.readFileDescriptor() : null;
-            boolean res = dumpHeap(process, managed, path, fd);
+            boolean res = dumpHeap(process, userId, managed, path, fd);
             reply.writeNoException();
             reply.writeInt(res ? 1 : 0);
             return true;
@@ -3264,11 +3268,12 @@
         reply.recycle();
     }
 
-    public void killBackgroundProcesses(String packageName) throws RemoteException {
+    public void killBackgroundProcesses(String packageName, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeString(packageName);
+        data.writeInt(userId);
         mRemote.transact(KILL_BACKGROUND_PROCESSES_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -3285,11 +3290,12 @@
         reply.recycle();
     }
 
-    public void forceStopPackage(String packageName) throws RemoteException {
+    public void forceStopPackage(String packageName, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeString(packageName);
+        data.writeInt(userId);
         mRemote.transact(FORCE_STOP_PACKAGE_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -3322,13 +3328,14 @@
         return res;
     }
     
-    public boolean profileControl(String process, boolean start,
+    public boolean profileControl(String process, int userId, boolean start,
             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeString(process);
+        data.writeInt(userId);
         data.writeInt(start ? 1 : 0);
         data.writeInt(profileType);
         data.writeString(path);
@@ -3601,12 +3608,13 @@
         return res;
     }
 
-    public boolean dumpHeap(String process, boolean managed,
+    public boolean dumpHeap(String process, int userId, boolean managed,
             String path, ParcelFileDescriptor fd) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeString(process);
+        data.writeInt(userId);
         data.writeInt(managed ? 1 : 0);
         data.writeString(path);
         if (fd != null) {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 38e6970..812ac9e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -52,6 +52,7 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Debug;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -4066,7 +4067,8 @@
 
         // send up app name; do this *before* waiting for debugger
         Process.setArgV0(data.processName);
-        android.ddm.DdmHandleAppName.setAppName(data.processName);
+        android.ddm.DdmHandleAppName.setAppName(data.processName,
+                                                UserHandle.myUserId());
 
         if (data.persistent) {
             // Persistent processes on low-memory devices do not get to
@@ -4792,7 +4794,8 @@
                     ensureJitEnabled();
                 }
             });
-            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
+            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
+                                                    UserHandle.myUserId());
             RuntimeInit.setApplicationObject(mAppThread.asBinder());
             IActivityManager mgr = ActivityManagerNative.getDefault();
             try {
@@ -4803,7 +4806,8 @@
         } else {
             // Don't set application object here -- if the system crashes,
             // we can't display an alert, we just want to die die die.
-            android.ddm.DdmHandleAppName.setAppName("system_process");
+            android.ddm.DdmHandleAppName.setAppName("system_process",
+                                                    UserHandle.myUserId());
             try {
                 mInstrumentation = new Instrumentation();
                 ContextImpl context = new ContextImpl();
@@ -4874,6 +4878,8 @@
         // StrictMode) on debug builds, but using DropBox, not logs.
         CloseGuard.setEnabled(false);
 
+        Environment.initForCurrentUser();
+
         Security.addProvider(new AndroidKeyStoreProvider());
 
         Process.setArgV0("<pre-initialized>");
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 3498919..92104fa 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1503,7 +1503,7 @@
                     (message != null ? (message + ": ") : "") +
                     (selfToo
                      ? "Neither user " + uid + " nor current process has "
-                     : "User " + uid + " does not have ") +
+                     : "uid " + uid + " does not have ") +
                     permission +
                     ".");
         }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 9cb3621..4c0e2a7 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -208,9 +208,10 @@
     
     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) throws RemoteException;
     
-    public void killBackgroundProcesses(final String packageName) throws RemoteException;
+    public void killBackgroundProcesses(final String packageName, int userId)
+            throws RemoteException;
     public void killAllBackgroundProcesses() throws RemoteException;
-    public void forceStopPackage(final String packageName) throws RemoteException;
+    public void forceStopPackage(final String packageName, int userId) throws RemoteException;
     
     // Note: probably don't want to allow applications access to these.
     public void goingToSleep() throws RemoteException;
@@ -267,7 +268,7 @@
     public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException;
     
     // Turn on/off profiling in a particular process.
-    public boolean profileControl(String process, boolean start,
+    public boolean profileControl(String process, int userId, boolean start,
             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException;
     
     public boolean shutdown(int timeout) throws RemoteException;
@@ -308,7 +309,7 @@
             Uri uri, int modeFlags) throws RemoteException;
 
     // Cause the specified process to dump the specified heap.
-    public boolean dumpHeap(String process, boolean managed, String path,
+    public boolean dumpHeap(String process, int userId, boolean managed, String path,
         ParcelFileDescriptor fd) throws RemoteException;
 
     public int startActivities(IApplicationThread caller,
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 603ceb7..c86826f 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -513,7 +513,17 @@
                         theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                 inflater = inflater.cloneInContext(theirContext);
                 inflater.setFilter(sInflaterFilter);
-                defaultView = inflater.inflate(mInfo.initialLayout, this, false);
+                AppWidgetManager manager = AppWidgetManager.getInstance(mContext);
+                Bundle options = manager.getAppWidgetOptions(mAppWidgetId);
+
+                int layoutId = mInfo.initialLayout;
+                if (options.containsKey(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)) {
+                    int category = options.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY);
+                    if (category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD) {
+                        layoutId = mInfo.initialKeyguardLayout;
+                    }
+                }
+                defaultView = inflater.inflate(layoutId, this, false);
             } else {
                 Log.w(TAG, "can't inflate defaultView because mInfo is missing");
             }
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 810e790..100a2b8 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -150,26 +150,34 @@
     public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
 
     /**
-     * An bundle extra that contains the lower bound on the current width, in dips, of a widget instance.
+     * A bundle extra that contains the lower bound on the current width, in dips, of a widget instance.
      */
     public static final String OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth";
 
     /**
-     * An bundle extra that contains the lower bound on the current height, in dips, of a widget instance.
+     * A bundle extra that contains the lower bound on the current height, in dips, of a widget instance.
      */
     public static final String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight";
 
     /**
-     * An bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
+     * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
      */
     public static final String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth";
 
     /**
-     * An bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
+     * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
      */
     public static final String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight";
 
     /**
+     * A bundle extra that hints to the AppWidgetProvider the category of host that owns this
+     * this widget. Can have the value {@link
+     * AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or {@link
+     * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD}.
+     */
+    public static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
+
+    /**
      * An intent extra which points to a bundle of extra information for a particular widget id.
      * In particular this bundle can contain EXTRA_APPWIDGET_WIDTH and EXTRA_APPWIDGET_HEIGHT.
      */
@@ -237,8 +245,9 @@
     /**
      * Sent when the custom extras for an AppWidget change.
      *
-     * @see AppWidgetProvider#onAppWidgetExtrasChanged AppWidgetProvider#onAppWidgetExtrasChanged(
-     *      Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
+     * @see AppWidgetProvider#onAppWidgetOptionsChanged 
+     *      AppWidgetProvider.onAppWidgetOptionsChanged(Context context, 
+     *      AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
      */
     public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
 
@@ -567,7 +576,31 @@
      */
     public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
         try {
-            sService.bindAppWidgetId(appWidgetId, provider);
+            sService.bindAppWidgetId(appWidgetId, provider, null);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    /**
+     * Set the component for a given appWidgetId.
+     *
+     * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
+     *         widgets always for your component. This method is used by the AppWidget picker and
+     *         should not be used by other apps.
+     *
+     * @param appWidgetId     The AppWidget instance for which to set the RemoteViews.
+     * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
+     *                      provider for this AppWidget.
+     * @param options       Bundle containing options for the AppWidget. See also
+     *                      {@link #updateAppWidgetOptions(int, Bundle)}
+     *
+     * @hide
+     */
+    public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
+        try {
+            sService.bindAppWidgetId(appWidgetId, provider, options);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -593,7 +626,37 @@
         }
         try {
             return sService.bindAppWidgetIdIfAllowed(
-                    mContext.getPackageName(), appWidgetId, provider);
+                    mContext.getPackageName(), appWidgetId, provider, null);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    /**
+     * Set the component for a given appWidgetId.
+     *
+     * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
+     *         widgets always for your component. Should be used by apps that host widgets; if this
+     *         method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
+     *         bind
+     *
+     * @param appWidgetId     The AppWidget instance for which to set the RemoteViews.
+     * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
+     *                      provider for this AppWidget.
+     * @param options       Bundle containing options for the AppWidget. See also
+     *                      {@link #updateAppWidgetOptions(int, Bundle)}
+     *
+     * @return true if this component has permission to bind the AppWidget
+     */
+    public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider,
+            Bundle options) {
+        if (mContext == null) {
+            return false;
+        }
+        try {
+            return sService.bindAppWidgetIdIfAllowed(
+                    mContext.getPackageName(), appWidgetId, provider, options);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index c33681d..5ef3d39 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -44,6 +44,34 @@
     public static final int RESIZE_BOTH = RESIZE_HORIZONTAL | RESIZE_VERTICAL;
 
     /**
+     * Indicates that the widget can be displayed on the home screen. This is the default value.
+     */
+    public static final int WIDGET_CATEGORY_HOME_SCREEN = 1;
+
+    /**
+     * Indicates that the widget can be displayed on the keyguard.
+     */
+    public static final int WIDGET_CATEGORY_KEYGUARD = 2;
+
+    /**
+     * Indicates that the widget supports no special features.
+     */
+    public static final int WIDGET_FEATURES_NONE = 0;
+
+    /**
+     * Indicates that the widget displays the current time. The host may use this as a hint to not
+     * display the time in other places.
+     */
+    public static final int WIDGET_FEATURES_CLOCK = 1;
+
+    /**
+     * Indicates that the widget is output only, ie. has nothing clickable. This may be enforced by
+     * the host. Presently, this flag is used by the keyguard to indicate that it can be placed
+     * in the first position.
+     */
+    public static final int WIDGET_FEATURES_STATUS = 2;
+
+    /**
      * Identity of this AppWidget component.  This component should be a {@link
      * android.content.BroadcastReceiver}, and it will be sent the AppWidget intents
      * {@link android.appwidget as described in the AppWidget package documentation}.
@@ -111,6 +139,16 @@
     public int initialLayout;
 
     /**
+     * The resource id of the initial layout for this AppWidget when it is displayed on keyguard.
+     * This parameter only needs to be provided if the widget can be displayed on the keyguard,
+     * see {@link #widgetCategory}.
+     *
+     * <p>This field corresponds to the <code>android:initialKeyguardLayout</code> attribute in
+     * the AppWidget meta-data file.
+     */
+    public int initialKeyguardLayout;
+
+    /**
      * The activity to launch that will configure the AppWidget.
      *
      * <p>This class name of field corresponds to the <code>android:configure</code> attribute in
@@ -164,6 +202,27 @@
      */
     public int resizeMode;
 
+    /**
+     * Determines whether this widget can be displayed on the home screen, the keyguard, or both.
+     * A widget which is displayed on both needs to ensure that it follows the design guidelines
+     * for both widget classes. This can be achieved by querying the AppWidget options in its
+     * widget provider's update method.
+     *
+     * <p>This field corresponds to the <code>widgetCategory</code> attribute in
+     * the AppWidget meta-data file.
+     */
+    public int widgetCategory;
+
+    /**
+     * A field which specifies any special features that this widget supports. See
+     * {@link #WIDGET_FEATURES_NONE}, {@link #WIDGET_FEATURES_CLOCK},
+     * {@link #WIDGET_FEATURES_STATUS}.
+     *
+     * <p>This field corresponds to the <code>widgetFeatures</code> attribute in
+     * the AppWidget meta-data file.
+     */
+    public int widgetFeatures;
+
     public AppWidgetProviderInfo() {
     }
 
@@ -180,6 +239,7 @@
         this.minResizeHeight = in.readInt();
         this.updatePeriodMillis = in.readInt();
         this.initialLayout = in.readInt();
+        this.initialKeyguardLayout = in.readInt();
         if (0 != in.readInt()) {
             this.configure = new ComponentName(in);
         }
@@ -188,6 +248,8 @@
         this.previewImage = in.readInt();
         this.autoAdvanceViewId = in.readInt();
         this.resizeMode = in.readInt();
+        this.widgetCategory = in.readInt();
+        this.widgetFeatures = in.readInt();
     }
 
     public void writeToParcel(android.os.Parcel out, int flags) {
@@ -203,6 +265,7 @@
         out.writeInt(this.minResizeHeight);
         out.writeInt(this.updatePeriodMillis);
         out.writeInt(this.initialLayout);
+        out.writeInt(this.initialKeyguardLayout);
         if (this.configure != null) {
             out.writeInt(1);
             this.configure.writeToParcel(out, flags);
@@ -214,6 +277,8 @@
         out.writeInt(this.previewImage);
         out.writeInt(this.autoAdvanceViewId);
         out.writeInt(this.resizeMode);
+        out.writeInt(this.widgetCategory);
+        out.writeInt(this.widgetFeatures);
     }
 
     public int describeContents() {
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 060a235..6bc9a1f 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -18,7 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Parcelable.Creator;
+import android.os.UserHandle;
 
 /**
  * Per-user information.
@@ -92,6 +92,10 @@
         serialNumber = orig.serialNumber;
     }
 
+    public UserHandle getUserHandle() {
+        return new UserHandle(id);
+    }
+
     @Override
     public String toString() {
         return "UserInfo{" + id + ":" + name + ":" + Integer.toHexString(flags) + "}";
diff --git a/core/java/android/ddm/DdmHandleAppName.java b/core/java/android/ddm/DdmHandleAppName.java
index 78dd23e..7e39e47 100644
--- a/core/java/android/ddm/DdmHandleAppName.java
+++ b/core/java/android/ddm/DdmHandleAppName.java
@@ -69,14 +69,14 @@
      * before or after DDMS connects.  For the latter we need to send up
      * an APNM message.
      */
-    public static void setAppName(String name) {
+    public static void setAppName(String name, int userId) {
         if (name == null || name.length() == 0)
             return;
 
         mAppName = name;
 
         // if DDMS is already connected, send the app name up
-        sendAPNM(name);
+        sendAPNM(name, userId);
     }
 
     public static String getAppName() {
@@ -86,14 +86,18 @@
     /*
      * Send an APNM (APplication NaMe) chunk.
      */
-    private static void sendAPNM(String appName) {
+    private static void sendAPNM(String appName, int userId) {
         if (false)
             Log.v("ddm", "Sending app name");
 
-        ByteBuffer out = ByteBuffer.allocate(4 + appName.length()*2);
+        ByteBuffer out = ByteBuffer.allocate(
+                            4 /* appName's length */
+                            + appName.length()*2 /* appName */
+                            + 4 /* userId */);
         out.order(ChunkHandler.CHUNK_ORDER);
         out.putInt(appName.length());
         putString(out, appName);
+        out.putInt(userId);
 
         Chunk chunk = new Chunk(CHUNK_APNM, out);
         DdmServer.sendChunk(chunk);
diff --git a/core/java/android/ddm/DdmHandleHello.java b/core/java/android/ddm/DdmHandleHello.java
index 5088d22..e99fa92 100644
--- a/core/java/android/ddm/DdmHandleHello.java
+++ b/core/java/android/ddm/DdmHandleHello.java
@@ -21,6 +21,7 @@
 import org.apache.harmony.dalvik.ddmc.DdmServer;
 import android.util.Log;
 import android.os.Debug;
+import android.os.UserHandle;
 
 import java.nio.ByteBuffer;
 
@@ -119,7 +120,7 @@
         //    appName = "unknown";
         String appName = DdmHandleAppName.getAppName();
 
-        ByteBuffer out = ByteBuffer.allocate(16
+        ByteBuffer out = ByteBuffer.allocate(20
                             + vmIdent.length()*2 + appName.length()*2);
         out.order(ChunkHandler.CHUNK_ORDER);
         out.putInt(DdmServer.CLIENT_PROTOCOL_VERSION);
@@ -128,6 +129,7 @@
         out.putInt(appName.length());
         putString(out, vmIdent);
         putString(out, appName);
+        out.putInt(UserHandle.myUserId());
 
         Chunk reply = new Chunk(CHUNK_HELO, out);
 
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 829620b..08e0ebe 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1146,6 +1146,31 @@
     public native final void setDisplayOrientation(int degrees);
 
     /**
+     * Enable or disable the default shutter sound when taking a picture.
+     *
+     * By default, the camera plays the system-defined camera shutter sound when
+     * {@link #takePicture} is called. Using this method, the shutter sound can
+     * be disabled. It is strongly recommended that an alternative shutter sound
+     * is played in the {@link ShutterCallback} when the system shutter sound is
+     * disabled.
+     *
+     * Note that devices may not always allow control of the camera shutter
+     * sound. If the shutter sound cannot be controlled, this method will return
+     * false.
+     *
+     * @param enabled whether the camera should play the system shutter sound
+     *                when {@link #takePicture takePicture} is called.
+     * @return true if the shutter sound state was successfully changed. False
+     *         if the shutter sound cannot be controlled; in this case, the
+     *         application should not play its own shutter sound since the
+     *         system shutter sound will play when a picture is taken.
+     * @see #takePicture
+     * @see ShutterCallback
+     * @hide
+     */
+    public native final boolean enableShutterSound(boolean enabled);
+
+    /**
      * Callback interface for zoom changes during a smooth zoom operation.
      *
      * @see #setZoomChangeListener(OnZoomChangeListener)
@@ -1782,6 +1807,14 @@
         public static final String SCENE_MODE_BARCODE = "barcode";
 
         /**
+         * Capture a scene using high dynamic range imaging techniques. The
+         * camera will return an image that has an extended dynamic range
+         * compared to a regular capture. Capturing such an image may take
+         * longer than a regular capture.
+         */
+        public static final String SCENE_MODE_HDR = "hdr";
+
+        /**
          * Auto-focus mode. Applications should call {@link
          * #autoFocus(AutoFocusCallback)} to start the focus in this mode.
          */
@@ -2784,6 +2817,7 @@
          * @see #SCENE_MODE_SPORTS
          * @see #SCENE_MODE_PARTY
          * @see #SCENE_MODE_CANDLELIGHT
+         * @see #SCENE_MODE_BARCODE
          */
         public String getSceneMode() {
             return get(KEY_SCENE_MODE);
diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java
index 27af013..3c3182a 100644
--- a/core/java/android/inputmethodservice/AbstractInputMethodService.java
+++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java
@@ -149,6 +149,17 @@
                 callback.finishedEvent(seq, handled);
             }
         }
+
+        /**
+         * Take care of dispatching incoming generic motion events to the appropriate
+         * callbacks on the service, and tell the client when this is done.
+         */
+        public void dispatchGenericMotionEvent(int seq, MotionEvent event, EventCallback callback) {
+            boolean handled = onGenericMotionEvent(event);
+            if (callback != null) {
+                callback.finishedEvent(seq, handled);
+            }
+        }
     }
     
     /**
@@ -189,7 +200,25 @@
         return new IInputMethodWrapper(this, mInputMethod);
     }
     
+    /**
+     * Implement this to handle trackball events on your input method.
+     *
+     * @param event The motion event being received.
+     * @return True if the event was handled in this function, false otherwise.
+     * @see View#onTrackballEvent
+     */
     public boolean onTrackballEvent(MotionEvent event) {
         return false;
     }
+
+    /**
+     * Implement this to handle generic motion events on your input method.
+     *
+     * @param event The motion event being received.
+     * @return True if the event was handled in this function, false otherwise.
+     * @see View#onGenericMotionEvent
+     */
+    public boolean onGenericMotionEvent(MotionEvent event) {
+        return false;
+    }
 }
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index ce797d1..5324f81 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -43,6 +43,7 @@
     private static final int DO_UPDATE_EXTRACTED_TEXT = 67;
     private static final int DO_DISPATCH_KEY_EVENT = 70;
     private static final int DO_DISPATCH_TRACKBALL_EVENT = 80;
+    private static final int DO_DISPATCH_GENERIC_MOTION_EVENT = 85;
     private static final int DO_UPDATE_SELECTION = 90;
     private static final int DO_UPDATE_CURSOR = 95;
     private static final int DO_APP_PRIVATE_COMMAND = 100;
@@ -109,6 +110,15 @@
                 args.recycle();
                 return;
             }
+            case DO_DISPATCH_GENERIC_MOTION_EVENT: {
+                SomeArgs args = (SomeArgs)msg.obj;
+                mInputMethodSession.dispatchGenericMotionEvent(msg.arg1,
+                        (MotionEvent)args.arg1,
+                        new InputMethodEventCallbackWrapper(
+                                (IInputMethodCallback)args.arg2));
+                args.recycle();
+                return;
+            }
             case DO_UPDATE_SELECTION: {
                 SomeArgs args = (SomeArgs)msg.obj;
                 mInputMethodSession.updateSelection(args.argi1, args.argi2,
@@ -167,6 +177,12 @@
                 event, callback));
     }
 
+    public void dispatchGenericMotionEvent(int seq, MotionEvent event,
+            IInputMethodCallback callback) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageIOO(DO_DISPATCH_GENERIC_MOTION_EVENT, seq,
+                event, callback));
+    }
+
     public void updateSelection(int oldSelStart, int oldSelEnd,
             int newSelStart, int newSelEnd, int candidatesStart, int candidatesEnd) {
         mCaller.executeOrSendMessage(mCaller.obtainMessageIIIIII(DO_UPDATE_SELECTION,
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index d5b9edc..cf3b802 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1773,7 +1773,7 @@
      * Override this to intercept special key multiple events before they are
      * processed by the
      * application.  If you return true, the application will not itself
-     * process the event.  If you return true, the normal application processing
+     * process the event.  If you return false, the normal application processing
      * will occur as if the IME had not seen the event at all.
      * 
      * <p>The default implementation always returns false, except when
@@ -1788,7 +1788,7 @@
     /**
      * Override this to intercept key up events before they are processed by the
      * application.  If you return true, the application will not itself
-     * process the event.  If you return true, the normal application processing
+     * process the event.  If you return false, the normal application processing
      * will occur as if the IME had not seen the event at all.
      * 
      * <p>The default implementation intercepts {@link KeyEvent#KEYCODE_BACK
@@ -1806,8 +1806,29 @@
         return doMovementKey(keyCode, event, MOVEMENT_UP);
     }
 
+    /**
+     * Override this to intercept trackball motion events before they are
+     * processed by the application.
+     * If you return true, the application will not itself process the event.
+     * If you return false, the normal application processing will occur as if
+     * the IME had not seen the event at all.
+     */
     @Override
     public boolean onTrackballEvent(MotionEvent event) {
+        if (DEBUG) Log.v(TAG, "onTrackballEvent: " + event);
+        return false;
+    }
+
+    /**
+     * Override this to intercept generic motion events before they are
+     * processed by the application.
+     * If you return true, the application will not itself process the event.
+     * If you return false, the normal application processing will occur as if
+     * the IME had not seen the event at all.
+     */
+    @Override
+    public boolean onGenericMotionEvent(MotionEvent event) {
+        if (DEBUG) Log.v(TAG, "onGenericMotionEvent(): event " + event);
         return false;
     }
 
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index c52aa9e..3a06dc0 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -227,7 +227,7 @@
                     mIface = iface;
                     mNMService.setInterfaceUp(iface);
                     InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
-                    mLinkUp = config.isActive();
+                    mLinkUp = config.hasFlag("up");
                     if (config != null && mHwAddr == null) {
                         mHwAddr = config.getHardwareAddress();
                         if (mHwAddr != null) {
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 591cd0e..c08bfeb 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -95,7 +95,7 @@
      * Default trace file path and file
      */
     private static final String DEFAULT_TRACE_PATH_PREFIX =
-        Environment.getExternalStorageDirectory().getPath() + "/";
+        Environment.getLegacyExternalStorageDirectory().getPath() + "/";
     private static final String DEFAULT_TRACE_BODY = "dmtrace";
     private static final String DEFAULT_TRACE_EXTENSION = ".trace";
     private static final String DEFAULT_TRACE_FILE_PATH =
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 2fbcf3f..6667a41f 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -16,9 +16,10 @@
 
 package android.os;
 
-import android.content.res.Resources;
 import android.os.storage.IMountService;
+import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.File;
@@ -29,31 +30,125 @@
 public class Environment {
     private static final String TAG = "Environment";
 
+    private static final String ENV_EXTERNAL_STORAGE = "EXTERNAL_STORAGE";
+    private static final String ENV_EMULATED_STORAGE_TARGET = "EMULATED_STORAGE_TARGET";
+
     private static final File ROOT_DIRECTORY
             = getDirectory("ANDROID_ROOT", "/system");
 
     private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
 
-    private static final Object mLock = new Object();
+    private static UserEnvironment sCurrentUser;
 
-    private volatile static StorageVolume mPrimaryVolume = null;
+    private static final Object sLock = new Object();
+
+    // @GuardedBy("sLock")
+    private static volatile StorageVolume sPrimaryVolume;
 
     private static StorageVolume getPrimaryVolume() {
-        if (mPrimaryVolume == null) {
-            synchronized (mLock) {
-                if (mPrimaryVolume == null) {
+        if (sPrimaryVolume == null) {
+            synchronized (sLock) {
+                if (sPrimaryVolume == null) {
                     try {
                         IMountService mountService = IMountService.Stub.asInterface(ServiceManager
                                 .getService("mount"));
-                        Parcelable[] volumes = mountService.getVolumeList();
-                        mPrimaryVolume = (StorageVolume)volumes[0];
+                        final StorageVolume[] volumes = mountService.getVolumeList();
+                        sPrimaryVolume = StorageManager.getPrimaryVolume(volumes);
                     } catch (Exception e) {
                         Log.e(TAG, "couldn't talk to MountService", e);
                     }
                 }
             }
         }
-        return mPrimaryVolume;
+        return sPrimaryVolume;
+    }
+
+    static {
+        initForCurrentUser();
+    }
+
+    /** {@hide} */
+    public static void initForCurrentUser() {
+        final int userId = UserHandle.myUserId();
+        sCurrentUser = new UserEnvironment(userId);
+
+        synchronized (sLock) {
+            sPrimaryVolume = null;
+        }
+    }
+
+    /** {@hide} */
+    public static class UserEnvironment {
+        // TODO: generalize further to create package-specific environment
+
+        private final File mExternalStorage;
+        private final File mExternalStorageAndroidData;
+        private final File mExternalStorageAndroidMedia;
+        private final File mExternalStorageAndroidObb;
+
+        public UserEnvironment(int userId) {
+            // See storage config details at http://source.android.com/tech/storage/
+            String rawExternalStorage = System.getenv(ENV_EXTERNAL_STORAGE);
+            String rawEmulatedStorageTarget = System.getenv(ENV_EMULATED_STORAGE_TARGET);
+
+            if (!TextUtils.isEmpty(rawEmulatedStorageTarget)) {
+                // Device has emulated storage; external storage paths should have
+                // userId burned into them.
+                final File emulatedBase = new File(rawEmulatedStorageTarget);
+
+                // /storage/emulated/0
+                mExternalStorage = buildPath(emulatedBase, Integer.toString(userId));
+                // /storage/emulated/obb
+                mExternalStorageAndroidObb = buildPath(emulatedBase, "obb");
+
+            } else {
+                // Device has physical external storage; use plain paths.
+                if (TextUtils.isEmpty(rawExternalStorage)) {
+                    Log.w(TAG, "EXTERNAL_STORAGE undefined; falling back to default");
+                    rawExternalStorage = "/storage/sdcard0";
+                }
+
+                // /storage/sdcard0
+                mExternalStorage = new File(rawExternalStorage);
+                // /storage/sdcard0/Android/obb
+                mExternalStorageAndroidObb = buildPath(mExternalStorage, "Android", "obb");
+            }
+
+            mExternalStorageAndroidData = buildPath(mExternalStorage, "Android", "data");
+            mExternalStorageAndroidMedia = buildPath(mExternalStorage, "Android", "media");
+        }
+
+        public File getExternalStorageDirectory() {
+            return mExternalStorage;
+        }
+
+        public File getExternalStoragePublicDirectory(String type) {
+            return new File(mExternalStorage, type);
+        }
+
+        public File getExternalStorageAndroidDataDir() {
+            return mExternalStorageAndroidData;
+        }
+
+        public File getExternalStorageAppDataDirectory(String packageName) {
+            return new File(mExternalStorageAndroidData, packageName);
+        }
+
+        public File getExternalStorageAppMediaDirectory(String packageName) {
+            return new File(mExternalStorageAndroidMedia, packageName);
+        }
+
+        public File getExternalStorageAppObbDirectory(String packageName) {
+            return new File(mExternalStorageAndroidObb, packageName);
+        }
+
+        public File getExternalStorageAppFilesDirectory(String packageName) {
+            return new File(new File(mExternalStorageAndroidData, packageName), "files");
+        }
+
+        public File getExternalStorageAppCacheDirectory(String packageName) {
+            return new File(new File(mExternalStorageAndroidData, packageName), "cache");
+        }
     }
 
     /**
@@ -137,20 +232,7 @@
     private static final File MEDIA_STORAGE_DIRECTORY
             = getDirectory("MEDIA_STORAGE", "/data/media");
 
-    private static final File EXTERNAL_STORAGE_DIRECTORY
-            = getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0");
-
-    private static final File EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY = new File(new File(
-            getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0"), "Android"), "data");
-
-    private static final File EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY = new File(new File(
-            getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0"), "Android"), "media");
-
-    private static final File EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY = new File(new File(
-            getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0"), "Android"), "obb");
-
-    private static final File DOWNLOAD_CACHE_DIRECTORY
-            = getDirectory("DOWNLOAD_CACHE", "/cache");
+    private static final File DOWNLOAD_CACHE_DIRECTORY = getDirectory("DOWNLOAD_CACHE", "/cache");
 
     /**
      * Gets the Android data directory.
@@ -198,7 +280,13 @@
      * @see #isExternalStorageRemovable()
      */
     public static File getExternalStorageDirectory() {
-        return EXTERNAL_STORAGE_DIRECTORY;
+        throwIfSystem();
+        return sCurrentUser.getExternalStorageDirectory();
+    }
+
+    /** {@hide} */
+    public static File getLegacyExternalStorageDirectory() {
+        return new File(System.getenv(ENV_EXTERNAL_STORAGE));
     }
 
     /**
@@ -318,7 +406,8 @@
      * using it such as with {@link File#mkdirs File.mkdirs()}.
      */
     public static File getExternalStoragePublicDirectory(String type) {
-        return new File(getExternalStorageDirectory(), type);
+        throwIfSystem();
+        return sCurrentUser.getExternalStoragePublicDirectory(type);
     }
 
     /**
@@ -326,7 +415,8 @@
      * @hide
      */
     public static File getExternalStorageAndroidDataDir() {
-        return EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY;
+        throwIfSystem();
+        return sCurrentUser.getExternalStorageAndroidDataDir();
     }
     
     /**
@@ -334,7 +424,8 @@
      * @hide
      */
     public static File getExternalStorageAppDataDirectory(String packageName) {
-        return new File(EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY, packageName);
+        throwIfSystem();
+        return sCurrentUser.getExternalStorageAppDataDirectory(packageName);
     }
     
     /**
@@ -342,7 +433,8 @@
      * @hide
      */
     public static File getExternalStorageAppMediaDirectory(String packageName) {
-        return new File(EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY, packageName);
+        throwIfSystem();
+        return sCurrentUser.getExternalStorageAppMediaDirectory(packageName);
     }
     
     /**
@@ -350,7 +442,8 @@
      * @hide
      */
     public static File getExternalStorageAppObbDirectory(String packageName) {
-        return new File(EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY, packageName);
+        throwIfSystem();
+        return sCurrentUser.getExternalStorageAppObbDirectory(packageName);
     }
     
     /**
@@ -358,17 +451,17 @@
      * @hide
      */
     public static File getExternalStorageAppFilesDirectory(String packageName) {
-        return new File(new File(EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY,
-                packageName), "files");
+        throwIfSystem();
+        return sCurrentUser.getExternalStorageAppFilesDirectory(packageName);
     }
-    
+
     /**
      * Generates the path to an application's cache.
      * @hide
      */
     public static File getExternalStorageAppCacheDirectory(String packageName) {
-        return new File(new File(EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY,
-                packageName), "cache");
+        throwIfSystem();
+        return sCurrentUser.getExternalStorageAppCacheDirectory(packageName);
     }
     
     /**
@@ -441,9 +534,10 @@
         try {
             IMountService mountService = IMountService.Stub.asInterface(ServiceManager
                     .getService("mount"));
-            return mountService.getVolumeState(getExternalStorageDirectory()
-                    .toString());
-        } catch (Exception rex) {
+            final StorageVolume primary = getPrimaryVolume();
+            return mountService.getVolumeState(primary.getPath());
+        } catch (RemoteException rex) {
+            Log.w(TAG, "Failed to read external storage state; assuming REMOVED: " + rex);
             return Environment.MEDIA_REMOVED;
         }
     }
@@ -457,8 +551,8 @@
      * <p>See {@link #getExternalStorageDirectory()} for more information.
      */
     public static boolean isExternalStorageRemovable() {
-        StorageVolume volume = getPrimaryVolume();
-        return (volume != null && volume.isRemovable());
+        final StorageVolume primary = getPrimaryVolume();
+        return (primary != null && primary.isRemovable());
     }
 
     /**
@@ -475,12 +569,30 @@
      * android.content.ComponentName, boolean)} for additional details.
      */
     public static boolean isExternalStorageEmulated() {
-        StorageVolume volume = getPrimaryVolume();
-        return (volume != null && volume.isEmulated());
+        final StorageVolume primary = getPrimaryVolume();
+        return (primary != null && primary.isEmulated());
     }
 
     static File getDirectory(String variableName, String defaultPath) {
         String path = System.getenv(variableName);
         return path == null ? new File(defaultPath) : new File(path);
     }
+
+    private static void throwIfSystem() {
+        if (Process.myUid() == Process.SYSTEM_UID) {
+            Log.wtf(TAG, "Static storage paths aren't available from AID_SYSTEM", new Throwable());
+        }
+    }
+
+    private static File buildPath(File base, String... segments) {
+        File cur = base;
+        for (String segment : segments) {
+            if (cur == null) {
+                cur = new File(segment);
+            } else {
+                cur = new File(cur, segment);
+            }
+        }
+        return cur;
+    }
 }
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index fff7d5f..7e4666c 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -40,7 +40,7 @@
     /** @hide A user id to indicate that we would like to send to the current
      *  user, but if this is calling from a user process then we will send it
      *  to the caller's user instead of failing wiht a security exception */
-    public static final int USER_CURRENT_OR_SELF = -2;
+    public static final int USER_CURRENT_OR_SELF = -3;
 
     /** @hide A user handle to indicate that we would like to send to the current
      *  user, but if this is calling from a user process then we will send it
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index ab64866..0b16316 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -677,15 +677,15 @@
                 return _result;
             }
 
-            public Parcelable[] getVolumeList() throws RemoteException {
+            public StorageVolume[] getVolumeList() throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
-                Parcelable[] _result;
+                StorageVolume[] _result;
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
                     mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0);
                     _reply.readException();
-                    _result = _reply.readParcelableArray(StorageVolume.class.getClassLoader());
+                    _result = _reply.createTypedArray(StorageVolume.CREATOR);
                 } finally {
                     _reply.recycle();
                     _data.recycle();
@@ -1119,9 +1119,9 @@
                 }
                 case TRANSACTION_getVolumeList: {
                     data.enforceInterface(DESCRIPTOR);
-                    Parcelable[] result = getVolumeList();
+                    StorageVolume[] result = getVolumeList();
                     reply.writeNoException();
-                    reply.writeParcelableArray(result, 0);
+                    reply.writeTypedArray(result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                     return true;
                 }
                 case TRANSACTION_getSecureContainerFilesystemPath: {
@@ -1358,7 +1358,7 @@
     /**
      * Returns list of all mountable volumes.
      */
-    public Parcelable[] getVolumeList() throws RemoteException;
+    public StorageVolume[] getVolumeList() throws RemoteException;
 
     /**
      * Gets the path on the filesystem for the ASEC container itself.
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 8a20a6e..54c8709d 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -16,6 +16,8 @@
 
 package android.os.storage;
 
+import android.app.NotificationManager;
+import android.content.Context;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
@@ -285,6 +287,11 @@
         }
     }
 
+    /** {@hide} */
+    public static StorageManager from(Context context) {
+        return (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
+    }
+
     /**
      * Constructs a StorageManager object through which an application can
      * can communicate with the systems mount service.
@@ -594,4 +601,20 @@
         }
         return paths;
     }
+
+    /** {@hide} */
+    public StorageVolume getPrimaryVolume() {
+        return getPrimaryVolume(getVolumeList());
+    }
+
+    /** {@hide} */
+    public static StorageVolume getPrimaryVolume(StorageVolume[] volumes) {
+        for (StorageVolume volume : volumes) {
+            if (volume.isPrimary()) {
+                return volume;
+            }
+        }
+        Log.w(TAG, "No primary storage defined");
+        return null;
+    }
 }
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index b5983d1..177a955 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -19,16 +19,22 @@
 import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
+
+import java.io.File;
 
 /**
- * A class representing a storage volume
+ * Description of a storage volume and its capabilities, including the
+ * filesystem path where it may be mounted.
+ *
  * @hide
  */
 public class StorageVolume implements Parcelable {
 
+    // TODO: switch to more durable token
     private int mStorageId;
 
-    private final String mPath;
+    private final File mPath;
     private final int mDescriptionId;
     private final boolean mPrimary;
     private final boolean mRemovable;
@@ -37,14 +43,17 @@
     private final boolean mAllowMassStorage;
     /** Maximum file size for the storage, or zero for no limit */
     private final long mMaxFileSize;
+    /** When set, indicates exclusive ownership of this volume */
+    private final UserHandle mOwner;
 
     // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING,
     // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED,
     // ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts.
     public static final String EXTRA_STORAGE_VOLUME = "storage_volume";
 
-    public StorageVolume(String path, int descriptionId, boolean primary, boolean removable,
-            boolean emulated, int mtpReserveSpace, boolean allowMassStorage, long maxFileSize) {
+    public StorageVolume(File path, int descriptionId, boolean primary, boolean removable,
+            boolean emulated, int mtpReserveSpace, boolean allowMassStorage, long maxFileSize,
+            UserHandle owner) {
         mPath = path;
         mDescriptionId = descriptionId;
         mPrimary = primary;
@@ -53,18 +62,26 @@
         mMtpReserveSpace = mtpReserveSpace;
         mAllowMassStorage = allowMassStorage;
         mMaxFileSize = maxFileSize;
+        mOwner = owner;
     }
 
     private StorageVolume(Parcel in) {
         mStorageId = in.readInt();
-        mPath = in.readString();
+        mPath = new File(in.readString());
         mDescriptionId = in.readInt();
-        mPrimary = in.readByte() != 0;
-        mRemovable = in.readByte() != 0;
-        mEmulated = in.readByte() != 0;
+        mPrimary = in.readInt() != 0;
+        mRemovable = in.readInt() != 0;
+        mEmulated = in.readInt() != 0;
         mMtpReserveSpace = in.readInt();
-        mAllowMassStorage = in.readByte() != 0;
+        mAllowMassStorage = in.readInt() != 0;
         mMaxFileSize = in.readLong();
+        mOwner = in.readParcelable(null);
+    }
+
+    public static StorageVolume fromTemplate(StorageVolume template, File path, UserHandle owner) {
+        return new StorageVolume(path, template.mDescriptionId, template.mPrimary,
+                template.mRemovable, template.mEmulated, template.mMtpReserveSpace,
+                template.mAllowMassStorage, template.mMaxFileSize, owner);
     }
 
     /**
@@ -73,6 +90,10 @@
      * @return the mount path
      */
     public String getPath() {
+        return mPath.toString();
+    }
+
+    public File getPathFile() {
         return mPath;
     }
 
@@ -164,6 +185,10 @@
         return mMaxFileSize;
     }
 
+    public UserHandle getOwner() {
+        return mOwner;
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof StorageVolume && mPath != null) {
@@ -180,10 +205,19 @@
 
     @Override
     public String toString() {
-        return "StorageVolume [mAllowMassStorage=" + mAllowMassStorage + ", mDescriptionId="
-                + mDescriptionId + ", mEmulated=" + mEmulated + ", mMaxFileSize=" + mMaxFileSize
-                + ", mMtpReserveSpace=" + mMtpReserveSpace + ", mPath=" + mPath + ", mRemovable="
-                + mRemovable + ", mStorageId=" + mStorageId + "]";
+        final StringBuilder builder = new StringBuilder("StorageVolume [");
+        builder.append("mStorageId=").append(mStorageId);
+        builder.append(" mPath=").append(mPath);
+        builder.append(" mDescriptionId=").append(mDescriptionId);
+        builder.append(" mPrimary=").append(mPrimary);
+        builder.append(" mRemovable=").append(mRemovable);
+        builder.append(" mEmulated=").append(mEmulated);
+        builder.append(" mMtpReserveSpace=").append(mMtpReserveSpace);
+        builder.append(" mAllowMassStorage=").append(mAllowMassStorage);
+        builder.append(" mMaxFileSize=").append(mMaxFileSize);
+        builder.append(" mOwner=").append(mOwner);
+        builder.append("]");
+        return builder.toString();
     }
 
     public static final Creator<StorageVolume> CREATOR = new Creator<StorageVolume>() {
@@ -206,7 +240,7 @@
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mStorageId);
-        parcel.writeString(mPath);
+        parcel.writeString(mPath.toString());
         parcel.writeInt(mDescriptionId);
         parcel.writeInt(mPrimary ? 1 : 0);
         parcel.writeInt(mRemovable ? 1 : 0);
@@ -214,5 +248,6 @@
         parcel.writeInt(mMtpReserveSpace);
         parcel.writeInt(mAllowMassStorage ? 1 : 0);
         parcel.writeLong(mMaxFileSize);
+        parcel.writeParcelable(mOwner, flags);
     }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 841a076..1739205 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -739,6 +739,7 @@
             try {
                 Bundle arg = new Bundle();
                 arg.putString(Settings.NameValueTable.VALUE, value);
+                arg.putInt(CALL_METHOD_USER_KEY, userHandle);
                 IContentProvider cp = lazyGetProvider(cr);
                 cp.call(mCallSetCommand, name, arg);
             } catch (RemoteException e) {
diff --git a/core/java/android/service/dreams/DreamManagerService.java b/core/java/android/service/dreams/DreamManagerService.java
index 2cec6c3..4aa1cbb 100644
--- a/core/java/android/service/dreams/DreamManagerService.java
+++ b/core/java/android/service/dreams/DreamManagerService.java
@@ -5,15 +5,18 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
+import android.app.ActivityManagerNative;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
 import android.view.IWindowManager;
@@ -41,6 +44,7 @@
     private ComponentName mCurrentDreamComponent;
     private IDreamService mCurrentDream;
     private Binder mCurrentDreamToken;
+    private int mCurrentUserId;
 
     public DreamManagerService(Context context) {
         if (DEBUG) Slog.v(TAG, "DreamManagerService startup");
@@ -58,7 +62,7 @@
     // IDreamManager method
     @Override
     public void dream() {
-        ComponentName[] dreams = getDreamComponents();
+        ComponentName[] dreams = getDreamComponentsForUser(mCurrentUserId);
         ComponentName name = dreams != null && dreams.length > 0 ? dreams[0] : null;
         if (name != null) {
             synchronized (mLock) {
@@ -75,9 +79,10 @@
     // IDreamManager method
     @Override
     public void setDreamComponents(ComponentName[] componentNames) {
-        Settings.Secure.putString(mContext.getContentResolver(),
+        Settings.Secure.putStringForUser(mContext.getContentResolver(),
                 SCREENSAVER_COMPONENTS,
-                componentsToString(componentNames));
+                componentsToString(componentNames),
+                UserHandle.getCallingUserId());
     }
 
     private static String componentsToString(ComponentName[] componentNames) {
@@ -103,15 +108,22 @@
     // IDreamManager method
     @Override
     public ComponentName[] getDreamComponents() {
-        // TODO(dsandler) don't load this every time, watch the value
-        String names = Settings.Secure.getString(mContext.getContentResolver(), SCREENSAVER_COMPONENTS);
+        return getDreamComponentsForUser(UserHandle.getCallingUserId());
+    }
+
+    private ComponentName[] getDreamComponentsForUser(int userId) {
+        String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                SCREENSAVER_COMPONENTS,
+                userId);
         return names == null ? null : componentsFromString(names);
     }
 
     // IDreamManager method
     @Override
     public ComponentName getDefaultDreamComponent() {
-        String name = Settings.Secure.getString(mContext.getContentResolver(), SCREENSAVER_DEFAULT_COMPONENT);
+        String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                SCREENSAVER_DEFAULT_COMPONENT,
+                UserHandle.getCallingUserId());
         return name == null ? null : ComponentName.unflattenFromString(name);
     }
 
@@ -210,6 +222,25 @@
     }
 
     public void systemReady() {
+
+        // dream settings are kept per user, so keep track of current user
+        try {
+            mCurrentUserId = ActivityManagerNative.getDefault().getCurrentUser().id;
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Couldn't get current user ID; guessing it's 0", e);
+        }
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_USER_SWITCHED);
+        mContext.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+                    mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                    if (DEBUG) Slog.v(TAG, "userId " + mCurrentUserId + " is in the house");
+                }
+            }}, filter);
+
         if (DEBUG) Slog.v(TAG, "ready to dream!");
     }
 
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index b9f3942..a64cbf7 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -59,7 +59,7 @@
             in IInputContext inputContext);
     boolean inputMethodClientHasFocus(IInputMethodClient client);
 
-    void setForcedDisplaySize(int displayId, int longDimen, int shortDimen);
+    void setForcedDisplaySize(int displayId, int width, int height);
     void clearForcedDisplaySize(int displayId);
     void setForcedDisplayDensity(int displayId, int density);
     void clearForcedDisplayDensity(int displayId);
@@ -107,6 +107,9 @@
             IBinder freezeThisOneIfNeeded);
     void setNewConfiguration(in Configuration config);
     
+    void startFreezingScreen(int exitAnim, int enterAnim);
+    void stopFreezingScreen();
+
     // these require DISABLE_KEYGUARD permission
     void disableKeyguard(IBinder token, String tag);
     void reenableKeyguard(IBinder token);
diff --git a/core/java/android/view/InputEventConsistencyVerifier.java b/core/java/android/view/InputEventConsistencyVerifier.java
index fafe416..5dda934 100644
--- a/core/java/android/view/InputEventConsistencyVerifier.java
+++ b/core/java/android/view/InputEventConsistencyVerifier.java
@@ -322,7 +322,7 @@
 
         final int action = event.getAction();
         final boolean newStream = action == MotionEvent.ACTION_DOWN
-                || action == MotionEvent.ACTION_CANCEL;
+                || action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_OUTSIDE;
         if (newStream && (mTouchEventStreamIsTainted || mTouchEventStreamUnhandled)) {
             mTouchEventStreamIsTainted = false;
             mTouchEventStreamUnhandled = false;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 236adab..7567d88 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -39,7 +39,6 @@
 import android.graphics.Shader;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerGlobal;
 import android.os.Bundle;
 import android.os.Handler;
@@ -4275,25 +4274,42 @@
      * @return Whether any parent scrolled.
      */
     public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {
+        if (mAttachInfo == null) {
+            return false;
+        }
+
         View child = this;
+
+        RectF position = mAttachInfo.mTmpTransformRect;
+        position.set(rectangle);
+
         ViewParent parent = mParent;
         boolean scrolled = false;
         while (parent != null) {
+            rectangle.set((int) position.left, (int) position.top,
+                    (int) position.right, (int) position.bottom);
+
             scrolled |= parent.requestChildRectangleOnScreen(child,
                     rectangle, immediate);
 
-            // offset rect so next call has the rectangle in the
-            // coordinate system of its direct child.
-            rectangle.offset(child.getLeft(), child.getTop());
-            rectangle.offset(-child.getScrollX(), -child.getScrollY());
+            if (!child.hasIdentityMatrix()) {
+                child.getMatrix().mapRect(position);
+            }
+
+            position.offset(child.mLeft, child.mTop);
 
             if (!(parent instanceof View)) {
                 break;
             }
 
-            child = (View) parent;
+            View parentView = (View) parent;
+
+            position.offset(-parentView.getScrollX(), -parentView.getScrollY());
+
+            child = parentView;
             parent = child.getParent();
         }
+
         return scrolled;
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a4c0235..3006b5d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3211,6 +3211,33 @@
             mInputEventConsistencyVerifier.onTrackballEvent(event, 0);
         }
 
+        if (mView != null && mAdded && (q.mFlags & QueuedInputEvent.FLAG_DELIVER_POST_IME) == 0) {
+            if (LOCAL_LOGV)
+                Log.v(TAG, "Dispatching trackball " + event + " to " + mView);
+
+            // Dispatch to the IME before propagating down the view hierarchy.
+            // The IME will eventually call back into handleImeFinishedEvent.
+            if (mLastWasImTarget) {
+                InputMethodManager imm = InputMethodManager.peekInstance();
+                if (imm != null) {
+                    final int seq = event.getSequenceNumber();
+                    if (DEBUG_IMF)
+                        Log.v(TAG, "Sending trackball event to IME: seq="
+                                + seq + " event=" + event);
+                    imm.dispatchTrackballEvent(mView.getContext(), seq, event,
+                            mInputMethodCallback);
+                    return;
+                }
+            }
+        }
+
+        // Not dispatching to IME, continue with post IME actions.
+        deliverTrackballEventPostIme(q);
+    }
+
+    private void deliverTrackballEventPostIme(QueuedInputEvent q) {
+        final MotionEvent event = (MotionEvent) q.mEvent;
+
         // If there is no view, then the event will not be handled.
         if (mView == null || !mAdded) {
             finishInputEvent(q, false);
@@ -3344,8 +3371,33 @@
             mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0);
         }
 
-        final int source = event.getSource();
-        final boolean isJoystick = (source & InputDevice.SOURCE_CLASS_JOYSTICK) != 0;
+        if (mView != null && mAdded && (q.mFlags & QueuedInputEvent.FLAG_DELIVER_POST_IME) == 0) {
+            if (LOCAL_LOGV)
+                Log.v(TAG, "Dispatching generic motion " + event + " to " + mView);
+
+            // Dispatch to the IME before propagating down the view hierarchy.
+            // The IME will eventually call back into handleImeFinishedEvent.
+            if (mLastWasImTarget) {
+                InputMethodManager imm = InputMethodManager.peekInstance();
+                if (imm != null) {
+                    final int seq = event.getSequenceNumber();
+                    if (DEBUG_IMF)
+                        Log.v(TAG, "Sending generic motion event to IME: seq="
+                                + seq + " event=" + event);
+                    imm.dispatchGenericMotionEvent(mView.getContext(), seq, event,
+                            mInputMethodCallback);
+                    return;
+                }
+            }
+        }
+
+        // Not dispatching to IME, continue with post IME actions.
+        deliverGenericMotionEventPostIme(q);
+    }
+
+    private void deliverGenericMotionEventPostIme(QueuedInputEvent q) {
+        final MotionEvent event = (MotionEvent) q.mEvent;
+        final boolean isJoystick = (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0;
 
         // If there is no view, then the event will not be handled.
         if (mView == null || !mAdded) {
@@ -3366,7 +3418,8 @@
         }
 
         if (isJoystick) {
-            // Translate the joystick event into DPAD keys and try to deliver those.
+            // Translate the joystick event into DPAD keys and try to deliver
+            // those.
             updateJoystickDirection(event, true);
             finishInputEvent(q, true);
         } else {
@@ -3521,13 +3574,7 @@
             mInputEventConsistencyVerifier.onKeyEvent(event, 0);
         }
 
-        if ((q.mFlags & QueuedInputEvent.FLAG_DELIVER_POST_IME) == 0) {
-            // If there is no view, then the event will not be handled.
-            if (mView == null || !mAdded) {
-                finishInputEvent(q, false);
-                return;
-            }
-
+        if (mView != null && mAdded && (q.mFlags & QueuedInputEvent.FLAG_DELIVER_POST_IME) == 0) {
             if (LOCAL_LOGV) Log.v(TAG, "Dispatching key " + event + " to " + mView);
 
             // Perform predispatching before the IME.
@@ -3557,15 +3604,23 @@
     void handleImeFinishedEvent(int seq, boolean handled) {
         final QueuedInputEvent q = mCurrentInputEvent;
         if (q != null && q.mEvent.getSequenceNumber() == seq) {
-            final KeyEvent event = (KeyEvent)q.mEvent;
             if (DEBUG_IMF) {
                 Log.v(TAG, "IME finished event: seq=" + seq
-                        + " handled=" + handled + " event=" + event);
+                        + " handled=" + handled + " event=" + q);
             }
             if (handled) {
                 finishInputEvent(q, true);
             } else {
-                deliverKeyEventPostIme(q);
+                if (q.mEvent instanceof KeyEvent) {
+                    deliverKeyEventPostIme(q);
+                } else {
+                    final int source = q.mEvent.getSource();
+                    if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
+                        deliverTrackballEventPostIme(q);
+                    } else {
+                        deliverGenericMotionEventPostIme(q);
+                    }
+                }
             }
         } else {
             if (DEBUG_IMF) {
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index 00875ae..7d16e14 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -45,13 +45,15 @@
 
     public final Rect touchableRegion = new Rect();
 
-    public int type;
+    public int type = UNDEFINED;
 
-    public float compatibilityScale;
+    public float compatibilityScale = UNDEFINED;
 
     public boolean visible;
 
-    public int displayId;
+    public int displayId = UNDEFINED;
+
+    public int layer = UNDEFINED;
 
     private WindowInfo() {
         /* do nothing - reduce visibility */
@@ -71,6 +73,7 @@
         parcel.writeFloat(compatibilityScale);
         parcel.writeInt(visible ? 1 : 0);
         parcel.writeInt(displayId);
+        parcel.writeInt(layer);
         recycle();
     }
 
@@ -82,6 +85,7 @@
         compatibilityScale = parcel.readFloat();
         visible = (parcel.readInt() == 1);
         displayId = parcel.readInt();
+        layer = parcel.readInt();
     }
 
     public static WindowInfo obtain(WindowInfo other) {
@@ -90,9 +94,10 @@
         info.frame.set(other.frame);
         info.touchableRegion.set(other.touchableRegion);
         info.type = other.type;
-        info.displayId = other.displayId;
         info.compatibilityScale = other.compatibilityScale;
         info.visible = other.visible;
+        info.displayId = other.displayId;
+        info.layer = other.layer;
         return info;
     }
 
@@ -131,8 +136,25 @@
         frame.setEmpty();
         touchableRegion.setEmpty();
         type = UNDEFINED;
-        displayId = UNDEFINED;
+        compatibilityScale = UNDEFINED;
         visible = false;
+        displayId = UNDEFINED;
+        layer = UNDEFINED;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("Window [token:").append((token != null) ? token.hashCode() : null);
+        builder.append(", displayId:").append(displayId);
+        builder.append(", type:").append(type);
+        builder.append(", visible:").append(visible);
+        builder.append(", layer:").append(layer);
+        builder.append(", compatibilityScale:").append(compatibilityScale);
+        builder.append(", frame:").append(frame);
+        builder.append(", touchableRegion:").append(touchableRegion);
+        builder.append("]");
+        return builder.toString();
     }
 
     /**
diff --git a/core/java/android/view/animation/RotateAnimation.java b/core/java/android/view/animation/RotateAnimation.java
index 67e0374..3c325d9 100644
--- a/core/java/android/view/animation/RotateAnimation.java
+++ b/core/java/android/view/animation/RotateAnimation.java
@@ -22,7 +22,7 @@
 
 /**
  * An animation that controls the rotation of an object. This rotation takes
- * place int the X-Y plane. You can specify the point to use for the center of
+ * place in the X-Y plane. You can specify the point to use for the center of
  * the rotation, where (0,0) is the top left point. If not specified, (0,0) is
  * the default rotation point.
  * 
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index e754adc..3ea6df3 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1593,7 +1593,7 @@
     /**
      * @hide
      */
-    void dispatchTrackballEvent(Context context, int seq, MotionEvent motion,
+    public void dispatchTrackballEvent(Context context, int seq, MotionEvent motion,
             FinishedEventCallback callback) {
         synchronized (mH) {
             if (DEBUG) Log.d(TAG, "dispatchTrackballEvent");
@@ -1614,6 +1614,30 @@
         callback.finishedEvent(seq, false);
     }
 
+    /**
+     * @hide
+     */
+    public void dispatchGenericMotionEvent(Context context, int seq, MotionEvent motion,
+            FinishedEventCallback callback) {
+        synchronized (mH) {
+            if (DEBUG) Log.d(TAG, "dispatchGenericMotionEvent");
+
+            if (mCurMethod != null && mCurrentTextBoxAttribute != null) {
+                try {
+                    if (DEBUG) Log.v(TAG, "DISPATCH GENERIC MOTION: " + mCurMethod);
+                    final long startTime = SystemClock.uptimeMillis();
+                    enqueuePendingEventLocked(startTime, seq, mCurId, callback);
+                    mCurMethod.dispatchGenericMotionEvent(seq, motion, mInputMethodCallback);
+                    return;
+                } catch (RemoteException e) {
+                    Log.w(TAG, "IME died: " + mCurId + " dropping generic motion: " + motion, e);
+                }
+            }
+        }
+
+        callback.finishedEvent(seq, false);
+    }
+
     void finishedEvent(int seq, boolean handled) {
         final FinishedEventCallback callback;
         synchronized (mH) {
diff --git a/core/java/android/view/inputmethod/InputMethodSession.java b/core/java/android/view/inputmethod/InputMethodSession.java
index ea6f5ee..6386299 100644
--- a/core/java/android/view/inputmethod/InputMethodSession.java
+++ b/core/java/android/view/inputmethod/InputMethodSession.java
@@ -138,6 +138,21 @@
     public void dispatchTrackballEvent(int seq, MotionEvent event, EventCallback callback);
 
     /**
+     * This method is called when there is a generic motion event.
+     *
+     * <p>
+     * If the input method wants to handle this event, return true, otherwise
+     * return false and the caller (i.e. the application) will handle the event.
+     *
+     * @param event The motion event.
+     *
+     * @return Whether the input method wants to handle this event.
+     *
+     * @see android.view.MotionEvent
+     */
+    public void dispatchGenericMotionEvent(int seq, MotionEvent event, EventCallback callback);
+
+    /**
      * Process a private command sent from the application to the input method.
      * This can be used to provide domain-specific features that are
      * only known between certain input methods and their clients.
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java
index fd73fda..a51a8f6 100644
--- a/core/java/android/webkit/AccessibilityInjector.java
+++ b/core/java/android/webkit/AccessibilityInjector.java
@@ -34,6 +34,7 @@
 
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -53,7 +54,7 @@
     private final WebView mWebView;
 
     // The Java objects that are exposed to JavaScript.
-    private TextToSpeech mTextToSpeech;
+    private TextToSpeechWrapper mTextToSpeech;
     private CallbackHandler mCallback;
 
     // Lazily loaded helper objects.
@@ -367,10 +368,7 @@
         if (mTextToSpeech != null) {
             return;
         }
-
-        final String pkgName = mContext.getPackageName();
-
-        mTextToSpeech = new TextToSpeech(mContext, null, null, pkgName + ".**webview**", true);
+        mTextToSpeech = new TextToSpeechWrapper(mContext);
         mWebView.addJavascriptInterface(mTextToSpeech, ALIAS_TTS_JS_INTERFACE);
     }
 
@@ -526,6 +524,41 @@
     }
 
     /**
+     * Used to protect the TextToSpeech class, only exposing the methods we want to expose.
+     */
+    private static class TextToSpeechWrapper {
+        private TextToSpeech mTextToSpeech;
+
+        public TextToSpeechWrapper(Context context) {
+            final String pkgName = context.getPackageName();
+            mTextToSpeech = new TextToSpeech(context, null, null, pkgName + ".**webview**", true);
+        }
+
+        @JavascriptInterface
+        @SuppressWarnings("unused")
+        public boolean isSpeaking() {
+            return mTextToSpeech.isSpeaking();
+        }
+
+        @JavascriptInterface
+        @SuppressWarnings("unused")
+        public int speak(String text, int queueMode, HashMap<String, String> params) {
+            return mTextToSpeech.speak(text, queueMode, params);
+        }
+
+        @JavascriptInterface
+        @SuppressWarnings("unused")
+        public int stop() {
+            return mTextToSpeech.stop();
+        }
+
+        @SuppressWarnings("unused")
+        protected void shutdown() {
+            mTextToSpeech.shutdown();
+        }
+    }
+
+    /**
      * Exposes result interface to JavaScript.
      */
     private static class CallbackHandler {
@@ -621,6 +654,7 @@
          * @param id The result id of the request as a {@link String}.
          * @param result The result of the request as a {@link String}.
          */
+        @JavascriptInterface
         @SuppressWarnings("unused")
         public void onResult(String id, String result) {
             final long resultId;
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 6074a0c..fea427d 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -89,16 +89,24 @@
     // Is this frame the main frame?
     private boolean mIsMainFrame;
 
+    // Javascript interface object
+    private class JSObject {
+        Object object;
+        boolean requireAnnotation;
+
+        public JSObject(Object object, boolean requireAnnotation) {
+            this.object = object;
+            this.requireAnnotation = requireAnnotation;
+        }
+    }
+
     // Attached Javascript interfaces
-    private Map<String, Object> mJavaScriptObjects;
+    private Map<String, JSObject> mJavaScriptObjects;
     private Set<Object> mRemovedJavaScriptObjects;
 
     // Key store handler when Chromium HTTP stack is used.
     private KeyStoreHandler mKeyStoreHandler = null;
 
-    // Implementation of the searchbox API.
-    private final SearchBoxImpl mSearchBox;
-
     // message ids
     // a message posted when a frame loading is completed
     static final int FRAME_COMPLETED = 1001;
@@ -234,10 +242,8 @@
         }
         sConfigCallback.addHandler(this);
 
-        mJavaScriptObjects = javascriptInterfaces;
-        if (mJavaScriptObjects == null) {
-            mJavaScriptObjects = new HashMap<String, Object>();
-        }
+        mJavaScriptObjects = new HashMap<String, JSObject>();
+        addJavaScriptObjects(javascriptInterfaces);
         mRemovedJavaScriptObjects = new HashSet<Object>();
 
         mSettings = settings;
@@ -246,8 +252,6 @@
         mDatabase = WebViewDatabaseClassic.getInstance(appContext);
         mWebViewCore = w;
 
-        mSearchBox = new SearchBoxImpl(mWebViewCore, mCallbackProxy);
-
         AssetManager am = context.getAssets();
         nativeCreateFrame(w, am, proxy.getBackForwardList());
 
@@ -590,15 +594,36 @@
         Iterator<String> iter = mJavaScriptObjects.keySet().iterator();
         while (iter.hasNext())  {
             String interfaceName = iter.next();
-            Object object = mJavaScriptObjects.get(interfaceName);
-            if (object != null) {
+            JSObject jsobject = mJavaScriptObjects.get(interfaceName);
+            if (jsobject != null && jsobject.object != null) {
                 nativeAddJavascriptInterface(nativeFramePointer,
-                        mJavaScriptObjects.get(interfaceName), interfaceName);
+                        jsobject.object, interfaceName, jsobject.requireAnnotation);
             }
         }
         mRemovedJavaScriptObjects.clear();
     }
 
+    /*
+     * Add javascript objects to the internal list of objects. The default behavior
+     * is to allow access to inherited methods (no annotation needed). This is only
+     * used when js objects are passed through a constructor (via a hidden constructor).
+     *
+     * @TODO change the default behavior to be compatible with the public addjavascriptinterface
+     */
+    private void addJavaScriptObjects(Map<String, Object> javascriptInterfaces) {
+
+        // TODO in a separate CL provide logic to enable annotations for API level JB_MR1 and above.
+        if (javascriptInterfaces == null) return;
+        Iterator<String> iter = javascriptInterfaces.keySet().iterator();
+        while (iter.hasNext())  {
+            String interfaceName = iter.next();
+            Object object = javascriptInterfaces.get(interfaceName);
+            if (object != null) {
+                mJavaScriptObjects.put(interfaceName, new JSObject(object, false));
+            }
+        }
+    }
+
     /**
      * This method is called by WebCore to check whether application
      * wants to hijack url loading
@@ -616,11 +641,11 @@
         }
     }
 
-    public void addJavascriptInterface(Object obj, String interfaceName) {
+    public void addJavascriptInterface(Object obj, String interfaceName,
+            boolean requireAnnotation) {
         assert obj != null;
         removeJavascriptInterface(interfaceName);
-
-        mJavaScriptObjects.put(interfaceName, obj);
+        mJavaScriptObjects.put(interfaceName, new JSObject(obj, requireAnnotation));
     }
 
     public void removeJavascriptInterface(String interfaceName) {
@@ -1187,10 +1212,6 @@
         }
     }
 
-    /*package*/ SearchBox getSearchBox() {
-        return mSearchBox;
-    }
-
     /**
      * Called by JNI when processing the X-Auto-Login header.
      */
@@ -1245,7 +1266,7 @@
      * Add a javascript interface to the main frame.
      */
     private native void nativeAddJavascriptInterface(int nativeFramePointer,
-            Object obj, String interfaceName);
+            Object obj, String interfaceName, boolean requireAnnotation);
 
     public native void clearCache();
 
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index b47cba8..a326da2 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -117,11 +117,8 @@
     private static final int ADD_HISTORY_ITEM                     = 135;
     private static final int HISTORY_INDEX_CHANGED                = 136;
     private static final int AUTH_CREDENTIALS                     = 137;
-    private static final int NOTIFY_SEARCHBOX_LISTENERS           = 139;
     private static final int AUTO_LOGIN                           = 140;
     private static final int CLIENT_CERT_REQUEST                  = 141;
-    private static final int SEARCHBOX_IS_SUPPORTED_CALLBACK      = 142;
-    private static final int SEARCHBOX_DISPATCH_COMPLETE_CALLBACK = 143;
     private static final int PROCEEDED_AFTER_SSL_ERROR            = 144;
 
     // Message triggered by the client to resume execution
@@ -871,14 +868,6 @@
                         host, realm, username, password);
                 break;
             }
-            case NOTIFY_SEARCHBOX_LISTENERS: {
-                SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();
-
-                @SuppressWarnings("unchecked")
-                List<String> suggestions = (List<String>) msg.obj;
-                searchBox.handleSuggestions(msg.getData().getString("query"), suggestions);
-                break;
-            }
             case AUTO_LOGIN: {
                 if (mWebViewClient != null) {
                     String realm = msg.getData().getString("realm");
@@ -889,19 +878,6 @@
                 }
                 break;
             }
-            case SEARCHBOX_IS_SUPPORTED_CALLBACK: {
-                SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();
-                Boolean supported = (Boolean) msg.obj;
-                searchBox.handleIsSupportedCallback(supported);
-                break;
-            }
-            case SEARCHBOX_DISPATCH_COMPLETE_CALLBACK: {
-                SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();
-                Boolean success = (Boolean) msg.obj;
-                searchBox.handleDispatchCompleteCallback(msg.getData().getString("function"),
-                        msg.getData().getInt("id"), success);
-                break;
-            }
         }
     }
 
@@ -1629,29 +1605,6 @@
         return mContext instanceof Activity;
     }
 
-    void onSearchboxSuggestionsReceived(String query, List<String> suggestions) {
-        Message msg = obtainMessage(NOTIFY_SEARCHBOX_LISTENERS);
-        msg.obj = suggestions;
-        msg.getData().putString("query", query);
-
-        sendMessage(msg);
-    }
-
-    void onIsSupportedCallback(boolean isSupported) {
-        Message msg = obtainMessage(SEARCHBOX_IS_SUPPORTED_CALLBACK);
-        msg.obj = Boolean.valueOf(isSupported);
-        sendMessage(msg);
-    }
-
-    void onSearchboxDispatchCompleteCallback(String function, int id, boolean success) {
-        Message msg = obtainMessage(SEARCHBOX_DISPATCH_COMPLETE_CALLBACK);
-        msg.obj = Boolean.valueOf(success);
-        msg.getData().putString("function", function);
-        msg.getData().putInt("id", id);
-
-        sendMessage(msg);
-    }
-
     private synchronized void sendMessageToUiThreadSync(Message msg) {
         sendMessage(msg);
         WebCoreThreadWatchdog.pause();
diff --git a/core/java/android/webkit/CertTool.java b/core/java/android/webkit/CertTool.java
index a2325c3..e4d09a9 100644
--- a/core/java/android/webkit/CertTool.java
+++ b/core/java/android/webkit/CertTool.java
@@ -16,6 +16,7 @@
 
 package android.webkit;
 
+import com.android.org.bouncycastle.asn1.ASN1Encoding;
 import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
 import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
 import com.android.org.bouncycastle.jce.netscape.NetscapeCertRequest;
@@ -57,7 +58,7 @@
             NetscapeCertRequest request = new NetscapeCertRequest(challenge,
                     MD5_WITH_RSA, pair.getPublic());
             request.sign(pair.getPrivate());
-            byte[] signed = request.toASN1Object().getDEREncoded();
+            byte[] signed = request.toASN1Primitive().getEncoded(ASN1Encoding.DER);
 
             Credentials.getInstance().install(context, pair);
             return new String(Base64.encode(signed));
diff --git a/core/java/android/webkit/JavascriptInterface.java b/core/java/android/webkit/JavascriptInterface.java
new file mode 100644
index 0000000..6cd2a7b
--- /dev/null
+++ b/core/java/android/webkit/JavascriptInterface.java
@@ -0,0 +1,35 @@
+/*
+ * 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.webkit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation that allows exposing methods to JavaScript. Starting from API level
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} and above, only methods explicitly
+ * marked with this annotation are available to the Javascript code. See
+ * {@link android.webkit.WebView#addJavascriptInterface} for more information about it.
+ *
+ */
+@SuppressWarnings("javadoc")
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface JavascriptInterface {
+}
\ No newline at end of file
diff --git a/core/java/android/webkit/SearchBox.java b/core/java/android/webkit/SearchBox.java
deleted file mode 100644
index 38a1740..0000000
--- a/core/java/android/webkit/SearchBox.java
+++ /dev/null
@@ -1,109 +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 android.webkit;
-
-import java.util.List;
-
-/**
- * Defines the interaction between the browser/renderer and the page running on
- * a given WebView frame, if the page supports the chromium SearchBox API.
- *
- * http://dev.chromium.org/searchbox
- *
- * The browser or container app can query the page for search results using
- * SearchBox.query() and receive suggestions by registering a listener on the
- * SearchBox object.
- *
- * @hide
- */
-public interface SearchBox {
-    /**
-     * Sets the current searchbox query. Note that the caller must call
-     * onchange() to ensure that the search page processes this query.
-     */
-    void setQuery(String query);
-
-    /**
-     * Verbatim is true if the caller suggests that the search page
-     * treat the current query as a verbatim search query (as opposed to a
-     * partially typed search query). As with setQuery, onchange() must be
-     * called to ensure that the search page processes the query.
-     */
-    void setVerbatim(boolean verbatim);
-
-    /**
-     * These attributes must contain the offset to the characters that immediately
-     * follow the start and end of the selection in the search box. If there is
-     * no such selection, then both selectionStart and selectionEnd must be the offset
-     * to the character that immediately follows the text entry cursor. In the case
-     * that there is no explicit text entry cursor, the cursor is
-     * implicitly at the end of the input.
-     */
-    void setSelection(int selectionStart, int selectionEnd);
-
-    /**
-     * Sets the dimensions of the view (if any) that overlaps the current
-     * window object. This is to ensure that the page renders results in
-     * a manner that allows them to not be obscured by such a view. Note
-     * that a call to onresize() is required if these dimensions change.
-     */
-    void setDimensions(int x, int y, int width, int height);
-
-    /**
-     * Notify the search page of any changes to the searchbox. Such as
-     * a change in the typed query (onchange), the user commiting a given query
-     * (onsubmit), or a change in size of a suggestions dropdown (onresize).
-     *
-     * @param listener an optional listener to notify of the success of the operation,
-     *      indicating if the javascript function existed and could be called or not.
-     *      It will be called on the UI thread.
-     */
-    void onchange(SearchBoxListener listener);
-    void onsubmit(SearchBoxListener listener);
-    void onresize(SearchBoxListener listener);
-    void oncancel(SearchBoxListener listener);
-
-    /**
-     * Add and remove listeners to the given Searchbox. Listeners are notified
-     * of any suggestions to the query that the underlying search engine might
-     * provide.
-     */
-    void addSearchBoxListener(SearchBoxListener l);
-    void removeSearchBoxListener(SearchBoxListener l);
-
-    /**
-     * Indicates if the searchbox API is supported in the current page.
-     */
-    void isSupported(IsSupportedCallback callback);
-
-    /**
-     * Listeners (if any) will be called on the thread that created the
-     * webview.
-     */
-    public abstract class SearchBoxListener {
-        public void onSuggestionsReceived(String query, List<String> suggestions) {}
-        public void onChangeComplete(boolean called) {}
-        public void onSubmitComplete(boolean called) {}
-        public void onResizeComplete(boolean called) {}
-        public void onCancelComplete(boolean called) {}
-    }
-
-    interface IsSupportedCallback {
-        void searchBoxIsSupported(boolean supported);
-    }
-}
diff --git a/core/java/android/webkit/SearchBoxImpl.java b/core/java/android/webkit/SearchBoxImpl.java
deleted file mode 100644
index 9942d25..0000000
--- a/core/java/android/webkit/SearchBoxImpl.java
+++ /dev/null
@@ -1,304 +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 android.webkit;
-
-import android.text.TextUtils;
-import android.util.Log;
-import android.webkit.WebViewCore.EventHub;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONStringer;
-
-/**
- * The default implementation of the SearchBox interface. Implemented
- * as a java bridge object and a javascript adapter that is called into
- * by the page hosted in the frame.
- */
-final class SearchBoxImpl implements SearchBox {
-    private static final String TAG = "WebKit.SearchBoxImpl";
-
-    /* package */ static final String JS_INTERFACE_NAME = "searchBoxJavaBridge_";
-
-    /* package */ static final String JS_BRIDGE
-            = "(function()"
-            + "{"
-            + "if (!window.chrome) {"
-            + "  window.chrome = {};"
-            + "}"
-            + "if (!window.chrome.searchBox) {"
-            + "  var sb = window.chrome.searchBox = {};"
-            + "  sb.setSuggestions = function(suggestions) {"
-            + "    if (window.searchBoxJavaBridge_) {"
-            + "      window.searchBoxJavaBridge_.setSuggestions(JSON.stringify(suggestions));"
-            + "    }"
-            + "  };"
-            + "  sb.setValue = function(valueArray) { sb.value = valueArray[0]; };"
-            + "  sb.value = '';"
-            + "  sb.x = 0;"
-            + "  sb.y = 0;"
-            + "  sb.width = 0;"
-            + "  sb.height = 0;"
-            + "  sb.selectionStart = 0;"
-            + "  sb.selectionEnd = 0;"
-            + "  sb.verbatim = false;"
-            + "}"
-            + "})();";
-
-    private static final String SET_QUERY_SCRIPT
-            = "if (window.chrome && window.chrome.searchBox) {"
-            + "  window.chrome.searchBox.setValue(%s);"
-            + "}";
-
-    private static final String SET_VERBATIM_SCRIPT
-            =  "if (window.chrome && window.chrome.searchBox) {"
-            + "  window.chrome.searchBox.verbatim = %1$s;"
-            + "}";
-
-    private static final String SET_SELECTION_SCRIPT
-            = "if (window.chrome && window.chrome.searchBox) {"
-            + "  var f = window.chrome.searchBox;"
-            + "  f.selectionStart = %d"
-            + "  f.selectionEnd = %d"
-            + "}";
-
-    private static final String SET_DIMENSIONS_SCRIPT
-            = "if (window.chrome && window.chrome.searchBox) { "
-            + "  var f = window.chrome.searchBox;"
-            + "  f.x = %d;"
-            + "  f.y = %d;"
-            + "  f.width = %d;"
-            + "  f.height = %d;"
-            + "}";
-
-    private static final String DISPATCH_EVENT_SCRIPT
-            = "if (window.chrome && window.chrome.searchBox && window.chrome.searchBox.on%1$s) {"
-            + "  window.chrome.searchBox.on%1$s();"
-            + "  window.searchBoxJavaBridge_.dispatchCompleteCallback('%1$s', %2$d, true);"
-            + "} else {"
-            + "  window.searchBoxJavaBridge_.dispatchCompleteCallback('%1$s', %2$d, false);"
-            + "}";
-
-    private static final String EVENT_CHANGE = "change";
-    private static final String EVENT_SUBMIT = "submit";
-    private static final String EVENT_RESIZE = "resize";
-    private static final String EVENT_CANCEL = "cancel";
-
-    private static final String IS_SUPPORTED_SCRIPT
-            = "if (window.searchBoxJavaBridge_) {"
-            + "  if (window.chrome && window.chrome.sv) {"
-            + "    window.searchBoxJavaBridge_.isSupportedCallback(true);"
-            + "  } else {"
-            + "    window.searchBoxJavaBridge_.isSupportedCallback(false);"
-            + "  }}";
-
-    private final List<SearchBoxListener> mListeners;
-    private final WebViewCore mWebViewCore;
-    private final CallbackProxy mCallbackProxy;
-    private IsSupportedCallback mSupportedCallback;
-    private int mNextEventId = 1;
-    private final HashMap<Integer, SearchBoxListener> mEventCallbacks;
-
-    SearchBoxImpl(WebViewCore webViewCore, CallbackProxy callbackProxy) {
-        mListeners = new ArrayList<SearchBoxListener>();
-        mWebViewCore = webViewCore;
-        mCallbackProxy = callbackProxy;
-        mEventCallbacks = new HashMap<Integer, SearchBoxListener>();
-    }
-
-    @Override
-    public void setQuery(String query) {
-        final String formattedQuery = jsonSerialize(query);
-        if (formattedQuery != null) {
-            final String js = String.format(SET_QUERY_SCRIPT, formattedQuery);
-            dispatchJs(js);
-        }
-    }
-
-    @Override
-    public void setVerbatim(boolean verbatim) {
-        final String js = String.format(SET_VERBATIM_SCRIPT, String.valueOf(verbatim));
-        dispatchJs(js);
-    }
-
-
-    @Override
-    public void setSelection(int selectionStart, int selectionEnd) {
-        final String js = String.format(SET_SELECTION_SCRIPT, selectionStart, selectionEnd);
-        dispatchJs(js);
-    }
-
-    @Override
-    public void setDimensions(int x, int y, int width, int height) {
-        final String js = String.format(SET_DIMENSIONS_SCRIPT, x, y, width, height);
-        dispatchJs(js);
-    }
-
-    @Override
-    public void onchange(SearchBoxListener callback) {
-        dispatchEvent(EVENT_CHANGE, callback);
-    }
-
-    @Override
-    public void onsubmit(SearchBoxListener callback) {
-        dispatchEvent(EVENT_SUBMIT, callback);
-    }
-
-    @Override
-    public void onresize(SearchBoxListener callback) {
-        dispatchEvent(EVENT_RESIZE, callback);
-    }
-
-    @Override
-    public void oncancel(SearchBoxListener callback) {
-        dispatchEvent(EVENT_CANCEL, callback);
-    }
-
-    private void dispatchEvent(String eventName, SearchBoxListener callback) {
-        int eventId;
-        if (callback != null) {
-            synchronized(this) {
-                eventId = mNextEventId++;
-                mEventCallbacks.put(eventId, callback);
-            }
-        } else {
-            eventId = 0;
-        }
-        final String js = String.format(DISPATCH_EVENT_SCRIPT, eventName, eventId);
-        dispatchJs(js);
-    }
-
-    private void dispatchJs(String js) {
-        mWebViewCore.sendMessage(EventHub.EXECUTE_JS, js);
-    }
-
-    @Override
-    public void addSearchBoxListener(SearchBoxListener l) {
-        synchronized (mListeners) {
-            mListeners.add(l);
-        }
-    }
-
-    @Override
-    public void removeSearchBoxListener(SearchBoxListener l) {
-        synchronized (mListeners) {
-            mListeners.remove(l);
-        }
-    }
-
-    @Override
-    public void isSupported(IsSupportedCallback callback) {
-        mSupportedCallback = callback;
-        dispatchJs(IS_SUPPORTED_SCRIPT);
-    }
-
-    // Called by Javascript through the Java bridge.
-    public void isSupportedCallback(boolean isSupported) {
-        mCallbackProxy.onIsSupportedCallback(isSupported);
-    }
-
-    public void handleIsSupportedCallback(boolean isSupported) {
-        IsSupportedCallback callback = mSupportedCallback;
-        mSupportedCallback = null;
-        if (callback != null) {
-            callback.searchBoxIsSupported(isSupported);
-        }
-    }
-
-    // Called by Javascript through the Java bridge.
-    public void dispatchCompleteCallback(String function, int id, boolean successful) {
-        mCallbackProxy.onSearchboxDispatchCompleteCallback(function, id, successful);
-    }
-
-    public void handleDispatchCompleteCallback(String function, int id, boolean successful) {
-        if (id != 0) {
-            SearchBoxListener listener;
-            synchronized(this) {
-                listener = mEventCallbacks.get(id);
-                mEventCallbacks.remove(id);
-            }
-            if (listener != null) {
-                if (TextUtils.equals(EVENT_CHANGE, function)) {
-                    listener.onChangeComplete(successful);
-                } else if (TextUtils.equals(EVENT_SUBMIT, function)) {
-                    listener.onSubmitComplete(successful);
-                } else if (TextUtils.equals(EVENT_RESIZE, function)) {
-                    listener.onResizeComplete(successful);
-                } else if (TextUtils.equals(EVENT_CANCEL, function)) {
-                    listener.onCancelComplete(successful);
-                }
-            }
-        }
-    }
-
-    // This is used as a hackish alternative to javascript escaping.
-    // There appears to be no such functionality in the core framework.
-    private static String jsonSerialize(String query) {
-        JSONStringer stringer = new JSONStringer();
-        try {
-            stringer.array().value(query).endArray();
-        } catch (JSONException e) {
-            Log.w(TAG, "Error serializing query : " + query);
-            return null;
-        }
-        return stringer.toString();
-    }
-
-    // Called by Javascript through the Java bridge.
-    public void setSuggestions(String jsonArguments) {
-        if (jsonArguments == null) {
-            return;
-        }
-
-        String query = null;
-        List<String> suggestions = new ArrayList<String>();
-        try {
-            JSONObject suggestionsJson = new JSONObject(jsonArguments);
-            query = suggestionsJson.getString("query");
-
-            final JSONArray suggestionsArray = suggestionsJson.getJSONArray("suggestions");
-            for (int i = 0; i < suggestionsArray.length(); ++i) {
-                final JSONObject suggestion = suggestionsArray.getJSONObject(i);
-                final String value = suggestion.getString("value");
-                if (value != null) {
-                    suggestions.add(value);
-                }
-                // We currently ignore the "type" of the suggestion. This isn't
-                // documented anywhere in the API documents.
-                // final String type = suggestions.getString("type");
-            }
-        } catch (JSONException je) {
-            Log.w(TAG, "Error parsing json [" + jsonArguments + "], exception = " + je);
-            return;
-        }
-
-        mCallbackProxy.onSearchboxSuggestionsReceived(query, suggestions);
-    }
-
-    /* package */ void handleSuggestions(String query, List<String> suggestions) {
-        synchronized (mListeners) {
-            for (int i = mListeners.size() - 1; i >= 0; i--) {
-                mListeners.get(i).onSuggestionsReceived(query, suggestions);
-            }
-        }
-    }
-}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index e8ff01f..a29ff37 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -102,7 +102,12 @@
 
     /**
      * Normal cache usage mode. Use with {@link #setCacheMode}.
+     *
+     * @deprecated This value is obsolete, as from API level
+     * {@link android.os.Build.VERSION_CODES#HONEYCOMB} and onwards it has the
+     * same effect as {@link #LOAD_DEFAULT}.
      */
+    @Deprecated
     public static final int LOAD_NORMAL = 0;
 
     /**
@@ -333,7 +338,10 @@
      * If it is true, WebView will choose a solution to maximize the performance.
      * e.g. the WebView's content may not be updated during the transition.
      * If it is false, WebView will keep its fidelity. The default value is false.
+     *
+     * @deprecated This method is now obsolete, and will become a no-op in future.
      */
+    @Deprecated
     public void setEnableSmoothTransition(boolean enable) {
         throw new MustOverrideException();
     }
@@ -343,7 +351,10 @@
      * zooming.
      *
      * @see #setEnableSmoothTransition
+     *
+     * @deprecated This method is now obsolete, and will become a no-op in future.
      */
+    @Deprecated
     public boolean enableSmoothTransition() {
         throw new MustOverrideException();
     }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 82635d7..05b86a3 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -469,7 +469,13 @@
      * @param defStyle the default style resource ID
      * @param privateBrowsing whether this WebView will be initialized in
      *                        private mode
+     *
+     * @deprecated Private browsing is no longer supported directly via 
+     * WebView and will be removed in a future release. Prefer using
+     * {@link WebSettings}, {@link WebViewDatabase}, {@link CookieManager}
+     * and {@link WebStorage} for fine-grained control of privacy data.
      */
+    @Deprecated
     public WebView(Context context, AttributeSet attrs, int defStyle,
             boolean privateBrowsing) {
         this(context, attrs, defStyle, null, privateBrowsing);
@@ -568,7 +574,11 @@
 
     /**
      * Sets the SSL certificate for the main top-level page.
+     *
+     * @deprecated Calling this function has no useful effect, and will be
+     * ignored in future releases.
      */
+    @Deprecated
     public void setCertificate(SslCertificate certificate) {
         checkThread();
         mProvider.setCertificate(certificate);
@@ -1017,7 +1027,12 @@
      * Gets the current scale of this WebView.
      *
      * @return the current scale
+     *
+     * @deprecated This method is prone to inaccuracy due to race conditions
+     * between the web rendering and UI threads; prefer
+     * {@link WebViewClient#onScaleChanged}.
      */
+    @Deprecated
     @ViewDebug.ExportedProperty(category = "webview")
     public float getScale() {
         checkThread();
@@ -1478,10 +1493,20 @@
     /**
      * Injects the supplied Java object into this WebView. The object is
      * injected into the JavaScript context of the main frame, using the
-     * supplied name. This allows the Java object's public methods to be
-     * accessed from JavaScript. Note that that injected objects will not
+     * supplied name. This allows the Java object's methods to be
+     * accessed from JavaScript. For API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
+     * and above, only public methods that are annotated with
+     * {@link android.webkit.JavascriptInterface} can be accessed from JavaScript.
+     * For API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or below,
+     * all public methods (including the inherited ones) can be accessed, see the
+     * important security note below for implications. Note that injected objects will not
      * appear in JavaScript until the page is next (re)loaded. For example:
-     * <pre> webView.addJavascriptInterface(new Object(), "injectedObject");
+     * <pre>
+     * class JsObject {
+     *    {@literal @}JavascriptInterface
+     *    public String toString() { return "injectedObject"; }
+     * }
+     * webView.addJavascriptInterface(new JsObject(), "injectedObject");
      * webView.loadData("<!DOCTYPE html><title></title>", "text/html", null);
      * webView.loadUrl("javascript:alert(injectedObject.toString())");</pre>
      * <p>
@@ -1489,7 +1514,9 @@
      * <ul>
      * <li> This method can be used to allow JavaScript to control the host
      * application. This is a powerful feature, but also presents a security
-     * risk, particularly as JavaScript could use reflection to access an
+     * risk for applications targeting API level
+     * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or below, because
+     * JavaScript could use reflection to access an
      * injected object's public fields. Use of this method in a WebView
      * containing untrusted content could allow an attacker to manipulate the
      * host application in unintended ways, executing Java code with the
@@ -1498,6 +1525,7 @@
      * <li> JavaScript interacts with Java object on a private, background
      * thread of this WebView. Care is therefore required to maintain thread
      * safety.</li>
+     * <li> The Java object's fields are not accessible.</li>
      * </ul>
      *
      * @param object the Java object to inject into this WebView's JavaScript
@@ -1594,6 +1622,10 @@
     public void onGlobalFocusChanged(View oldFocus, View newFocus) {
     }
 
+    /**
+     * @deprecated Only the default case, true, will be supported in a future version.
+     */
+    @Deprecated
     public void setMapTrackballToArrowKeys(boolean setMap) {
         checkThread();
         mProvider.setMapTrackballToArrowKeys(setMap);
@@ -1627,7 +1659,12 @@
      * Gets whether this WebView can be zoomed in.
      *
      * @return true if this WebView can be zoomed in
+     *
+     * @deprecated This method is prone to inaccuracy due to race conditions
+     * between the web rendering and UI threads; prefer
+     * {@link WebViewClient#onScaleChanged}.
      */
+    @Deprecated
     public boolean canZoomIn() {
         checkThread();
         return mProvider.canZoomIn();
@@ -1637,7 +1674,12 @@
      * Gets whether this WebView can be zoomed out.
      *
      * @return true if this WebView can be zoomed out
+     *
+     * @deprecated This method is prone to inaccuracy due to race conditions
+     * between the web rendering and UI threads; prefer
+     * {@link WebViewClient#onScaleChanged}.
      */
+    @Deprecated
     public boolean canZoomOut() {
         checkThread();
         return mProvider.canZoomOut();
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 9334036..d23f52c 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -27,7 +27,6 @@
 import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
@@ -56,6 +55,7 @@
 import android.net.Uri;
 import android.net.http.SslCertificate;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -69,7 +69,6 @@
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
-import android.view.Display;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
 import android.view.HardwareCanvas;
@@ -87,7 +86,6 @@
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.ViewRootImpl;
-import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -136,9 +134,6 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
-import java.util.concurrent.CountDownLatch;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * Implements a backend provider for the {@link WebView} public API.
@@ -1891,9 +1886,9 @@
                             mSavePasswordDialog = null;
                         }
                     })
-                    .setOnCancelListener(new OnCancelListener() {
+                    .setOnDismissListener(new DialogInterface.OnDismissListener() {
                         @Override
-                        public void onCancel(DialogInterface dialog) {
+                        public void onDismiss(DialogInterface dialog) {
                             if (mResumeMsg != null) {
                                 resumeMsg.sendToTarget();
                                 mResumeMsg = null;
@@ -2098,14 +2093,18 @@
         hideSoftKeyboard();
         clearActionModes();
         dismissFullScreenMode();
-        cancelSelectDialog();
+        cancelDialogs();
     }
 
-    private void cancelSelectDialog() {
+    private void cancelDialogs() {
         if (mListBoxDialog != null) {
             mListBoxDialog.cancel();
             mListBoxDialog = null;
         }
+        if (mSavePasswordDialog != null) {
+            mSavePasswordDialog.dismiss();
+            mSavePasswordDialog = null;
+        }
     }
 
     /**
@@ -2133,15 +2132,6 @@
 
     private void destroyJava() {
         mCallbackProxy.blockMessages();
-        clearHelpers();
-        if (mListBoxDialog != null) {
-            mListBoxDialog.dismiss();
-            mListBoxDialog = null;
-        }
-        if (mSavePasswordDialog != null) {
-            mSavePasswordDialog.dismiss();
-            mSavePasswordDialog = null;
-        }
         if (mWebViewCore != null) {
             // Tell WebViewCore to destroy itself
             synchronized (this) {
@@ -3492,7 +3482,7 @@
                 nativeSetPauseDrawing(mNativeClass, true);
             }
 
-            cancelSelectDialog();
+            cancelDialogs();
             WebCoreThreadWatchdog.pause();
         }
     }
@@ -4125,12 +4115,22 @@
      */
     @Override
     public void addJavascriptInterface(Object object, String name) {
+
         if (object == null) {
             return;
         }
         WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
+
         arg.mObject = object;
         arg.mInterfaceName = name;
+
+        // starting with JELLY_BEAN_MR1, annotations are mandatory for enabling access to
+        // methods that are accessible from JS.
+        if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            arg.mRequireAnnotation = true;
+        } else {
+            arg.mRequireAnnotation = false;
+        }
         mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
     }
 
@@ -5372,16 +5372,6 @@
     }
 
     /**
-     * This is an implementation detail.
-     */
-    public SearchBox getSearchBox() {
-        if ((mWebViewCore == null) || (mWebViewCore.getBrowserFrame() == null)) {
-            return null;
-        }
-        return mWebViewCore.getBrowserFrame().getSearchBox();
-    }
-
-    /**
      * Returns the currently highlighted text as a string.
      */
     String getSelection() {
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 59036e7..2d834ff 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -824,6 +824,7 @@
     static class JSInterfaceData {
         Object mObject;
         String mInterfaceName;
+        boolean mRequireAnnotation;
     }
 
     static class JSKeyData {
@@ -1489,7 +1490,7 @@
                         case ADD_JS_INTERFACE:
                             JSInterfaceData jsData = (JSInterfaceData) msg.obj;
                             mBrowserFrame.addJavascriptInterface(jsData.mObject,
-                                    jsData.mInterfaceName);
+                                    jsData.mInterfaceName, jsData.mRequireAnnotation);
                             break;
 
                         case REMOVE_JS_INTERFACE:
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index 7df45cf..cfb16fa 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -52,9 +52,9 @@
     AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId);
     boolean hasBindAppWidgetPermission(in String packageName);
     void setBindAppWidgetPermission(in String packageName, in boolean permission);
-    void bindAppWidgetId(int appWidgetId, in ComponentName provider);
+    void bindAppWidgetId(int appWidgetId, in ComponentName provider, in Bundle options);
     boolean bindAppWidgetIdIfAllowed(
-            in String packageName, int appWidgetId, in ComponentName provider);
+            in String packageName, int appWidgetId, in ComponentName provider, in Bundle options);
     void bindRemoteViewsService(int appWidgetId, in Intent intent, in IBinder connection);
     void unbindRemoteViewsService(int appWidgetId, in Intent intent);
     int[] getAppWidgetIds(in ComponentName provider);
diff --git a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
index 3905c88..fb7f215 100644
--- a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
+++ b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
@@ -122,7 +122,7 @@
     public void onCancel(DialogInterface dialog) {
         IMountService mountService = getMountService();
         String extStoragePath = mStorageVolume == null ?
-                Environment.getExternalStorageDirectory().toString() :
+                Environment.getLegacyExternalStorageDirectory().toString() :
                 mStorageVolume.getPath();
         try {
             mountService.mountVolume(extStoragePath);
@@ -149,7 +149,7 @@
             updateProgressDialog(R.string.progress_unmounting);
             IMountService mountService = getMountService();
             final String extStoragePath = mStorageVolume == null ?
-                    Environment.getExternalStorageDirectory().toString() :
+                    Environment.getLegacyExternalStorageDirectory().toString() :
                     mStorageVolume.getPath();
             try {
                 // Remove encryption mapping if this is an unmount for a factory reset.
@@ -163,7 +163,7 @@
             updateProgressDialog(R.string.progress_erasing);
             final IMountService mountService = getMountService();
             final String extStoragePath = mStorageVolume == null ?
-                    Environment.getExternalStorageDirectory().toString() :
+                    Environment.getLegacyExternalStorageDirectory().toString() :
                     mStorageVolume.getPath();
             if (mountService != null) {
                 new Thread() {
diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl
index f875cbd..cdec254 100644
--- a/core/java/com/android/internal/view/IInputMethodSession.aidl
+++ b/core/java/com/android/internal/view/IInputMethodSession.aidl
@@ -47,6 +47,8 @@
 
     void dispatchTrackballEvent(int seq, in MotionEvent event, IInputMethodCallback callback);
 
+    void dispatchGenericMotionEvent(int seq, in MotionEvent event, IInputMethodCallback callback);
+
     void appPrivateCommand(String action, in Bundle data);
 
     void toggleSoftInput(int showFlags, int hideFlags);
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 6cd8955..e1e97a1 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -781,6 +781,25 @@
     }
 }
 
+static jboolean android_hardware_Camera_enableShutterSound(JNIEnv *env, jobject thiz,
+        jboolean enabled)
+{
+    ALOGV("enableShutterSound");
+    sp<Camera> camera = get_native_camera(env, thiz, NULL);
+    if (camera == 0) return JNI_FALSE;
+
+    int32_t value = (enabled == JNI_TRUE) ? 1 : 0;
+    status_t rc = camera->sendCommand(CAMERA_CMD_ENABLE_SHUTTER_SOUND, value, 0);
+    if (rc == NO_ERROR) {
+        return JNI_TRUE;
+    } else if (rc == PERMISSION_DENIED) {
+        return JNI_FALSE;
+    } else {
+        jniThrowRuntimeException(env, "enable shutter sound failed");
+        return JNI_FALSE;
+    }
+}
+
 static void android_hardware_Camera_startFaceDetection(JNIEnv *env, jobject thiz,
         jint type)
 {
@@ -890,6 +909,9 @@
   { "setDisplayOrientation",
     "(I)V",
     (void *)android_hardware_Camera_setDisplayOrientation },
+  { "enableShutterSound",
+    "(Z)Z",
+    (void *)android_hardware_Camera_enableShutterSound },
   { "_startFaceDetection",
     "(I)V",
     (void *)android_hardware_Camera_startFaceDetection },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 560021d..58296de 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1265,6 +1265,13 @@
         android:description="@string/permdesc_manageAppTokens"
         android:protectionLevel="signature" />
 
+    <!-- @hide Allows the application to temporarily freeze the screen for a
+         full-screen transition. -->
+    <permission android:name="android.permission.FREEZE_SCREEN"
+        android:label="@string/permlab_freezeScreen"
+        android:description="@string/permdesc_freezeScreen"
+        android:protectionLevel="signature" />
+    
     <!-- Allows an application to inject user events (keys, touch, trackball)
          into the event stream and deliver them to ANY window.  Without this
          permission, you can only deliver events to windows in your own process.
@@ -1746,7 +1753,8 @@
                  android:allowClearUserData="false"
                  android:backupAgent="com.android.server.SystemBackupAgent"
                  android:killAfterRestore="false"
-                 android:icon="@drawable/ic_launcher_android">
+                 android:icon="@drawable/ic_launcher_android"
+                 android:supportsRtl="true">
         <activity android:name="com.android.internal.app.ChooserActivity"
                 android:theme="@style/Theme.Holo.Dialog.Alert"
                 android:finishOnCloseSystemDialogs="true"
diff --git a/core/res/res/anim/screen_user_enter.xml b/core/res/res/anim/screen_user_enter.xml
new file mode 100644
index 0000000..a73dea3
--- /dev/null
+++ b/core/res/res/anim/screen_user_enter.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 20012, 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:fromXDelta="100%p" android:toXDelta="0"
+            android:duration="500"
+            android:interpolator="@interpolator/decelerate_quad" />
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+            android:duration="500"
+            android:interpolator="@interpolator/decelerate_quad" />
+</set>
diff --git a/core/res/res/anim/screen_user_exit.xml b/core/res/res/anim/screen_user_exit.xml
new file mode 100644
index 0000000..ec94b76
--- /dev/null
+++ b/core/res/res/anim/screen_user_exit.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 20012, 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:fromXDelta="0" android:toXDelta="-100%p"
+            android:duration="500"
+            android:interpolator="@interpolator/decelerate_quad" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+            android:duration="500"
+            android:interpolator="@interpolator/decelerate_quad" />
+</set>
diff --git a/core/res/res/anim-port/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
similarity index 100%
rename from core/res/res/anim-port/task_close_enter.xml
rename to core/res/res/anim/task_close_enter.xml
diff --git a/core/res/res/anim-port/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
similarity index 100%
rename from core/res/res/anim-port/task_close_exit.xml
rename to core/res/res/anim/task_close_exit.xml
diff --git a/core/res/res/anim-port/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml
similarity index 100%
rename from core/res/res/anim-port/task_open_enter.xml
rename to core/res/res/anim/task_open_enter.xml
diff --git a/core/res/res/anim-port/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
similarity index 100%
rename from core/res/res/anim-port/task_open_exit.xml
rename to core/res/res/anim/task_open_exit.xml
diff --git a/core/res/res/layout-land/keyguard_host_view.xml b/core/res/res/layout-land/keyguard_host_view.xml
index 0028a54..8e7c232 100644
--- a/core/res/res/layout-land/keyguard_host_view.xml
+++ b/core/res/res/layout-land/keyguard_host_view.xml
@@ -38,7 +38,7 @@
     </com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
 
 
-    <ViewFlipper
+    <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
         android:id="@+id/view_flipper"
         android:layout_width="0dip"
         android:layout_height="match_parent"
@@ -48,6 +48,6 @@
         <!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
         <include layout="@layout/keyguard_selector_view"/>
 
-    </ViewFlipper>
+    </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
 
 </com.android.internal.policy.impl.keyguard.KeyguardHostView>
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index 5e467d1..55c4c0d 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -28,7 +28,7 @@
     android:gravity="center_horizontal"
     android:clipChildren="false">
 
-    <ViewFlipper
+    <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
         android:id="@+id/view_flipper"
         android:layout_height="match_parent"
         android:gravity="center">
@@ -36,7 +36,7 @@
         <!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
         <include layout="@layout/keyguard_selector_view"/>
 
-    </ViewFlipper>
+    </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
 
 </com.android.internal.policy.impl.keyguard.KeyguardHostView>
 
diff --git a/core/res/res/layout-sw600dp-land/keyguard_host_view.xml b/core/res/res/layout-sw600dp-land/keyguard_host_view.xml
index 5b6bb2f..652bdde 100644
--- a/core/res/res/layout-sw600dp-land/keyguard_host_view.xml
+++ b/core/res/res/layout-sw600dp-land/keyguard_host_view.xml
@@ -44,7 +44,7 @@
         android:layout_weight="1"
         android:gravity="center">
 
-        <ViewFlipper
+        <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
             android:id="@+id/view_flipper"
             android:layout_width="@dimen/kg_security_view_width"
             android:layout_height="match_parent"
@@ -55,7 +55,7 @@
             <!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
             <include layout="@layout/keyguard_selector_view"/>
 
-        </ViewFlipper>
+        </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
 
     </FrameLayout>
 
diff --git a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
index 397b881..0c1dd0c 100644
--- a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
+++ b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
@@ -40,7 +40,7 @@
 
     </com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
 
-    <ViewFlipper
+    <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
         android:id="@+id/view_flipper"
         android:layout_width="@dimen/kg_security_view_width"
         android:layout_height="0dip"
@@ -50,7 +50,7 @@
         <!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
         <include layout="@layout/keyguard_selector_view"/>
 
-    </ViewFlipper>
+    </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
 
 </com.android.internal.policy.impl.keyguard.KeyguardHostView>
 
diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml
index 954a92c..356bce3 100644
--- a/core/res/res/layout/keyguard_pattern_view.xml
+++ b/core/res/res/layout/keyguard_pattern_view.xml
@@ -23,42 +23,36 @@
 <com.android.internal.policy.impl.keyguard.KeyguardPatternView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/keyguard_pattern_view"
+    android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:gravity="center_horizontal">
 
-    <GridLayout
-        android:orientation="vertical"
+    <include layout="@layout/keyguard_navigation"/>
+
+    <Space android:layout_gravity="fill" />
+
+    <Button android:id="@+id/forgot_password_button"
+        android:layout_gravity="right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="@*android:dimen/keyguard_lockscreen_status_line_font_size"
+        android:drawableLeft="@*android:drawable/lockscreen_forgot_password_button"
+        android:drawablePadding="0dip"
+        android:visibility="gone"/>
+
+    <!-- We need MATCH_PARENT here only to force the size of the parent to be passed to
+    the pattern view for it to compute its size. This is an unusual case, caused by
+    LockPatternView's requirement to maintain a square aspect ratio based on the width
+    of the screen. -->
+    <com.android.internal.widget.LockPatternView
+        android:id="@+id/lockPatternView"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:gravity="center_horizontal">
-
-        <include layout="@layout/keyguard_navigation"/>
-
-        <Space android:layout_gravity="fill" />
-
-        <Button android:id="@+id/forgot_password_button"
-            android:layout_gravity="right"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textSize="@*android:dimen/keyguard_lockscreen_status_line_font_size"
-            android:drawableLeft="@*android:drawable/lockscreen_forgot_password_button"
-            android:drawablePadding="0dip"
-            android:visibility="gone"/>
-
-        <!-- We need MATCH_PARENT here only to force the size of the parent to be passed to
-        the pattern view for it to compute its size. This is an unusual case, caused by
-        LockPatternView's requirement to maintain a square aspect ratio based on the width
-        of the screen. -->
-        <com.android.internal.widget.LockPatternView
-            android:id="@+id/lockPatternView"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_marginEnd="8dip"
-            android:layout_marginBottom="4dip"
-            android:layout_marginStart="8dip"
-            android:layout_gravity="center_horizontal"
-         />
-
-    </GridLayout>
+        android:layout_marginEnd="8dip"
+        android:layout_marginBottom="4dip"
+        android:layout_marginStart="8dip"
+        android:layout_gravity="center_horizontal"
+     />
 
 </com.android.internal.policy.impl.keyguard.KeyguardPatternView>
diff --git a/core/res/res/layout/preference_holo.xml b/core/res/res/layout/preference_holo.xml
index 7a0a494..1cc803b 100644
--- a/core/res/res/layout/preference_holo.xml
+++ b/core/res/res/layout/preference_holo.xml
@@ -33,11 +33,12 @@
         android:orientation="horizontal">
         <ImageView
             android:id="@+android:id/icon"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
             android:layout_gravity="center"
             android:minWidth="48dp"
-            android:paddingRight="@dimen/preference_item_padding_inner"
+            android:scaleType="centerInside"
+            android:layout_marginEnd="@dimen/preference_item_padding_inner"
              />
     </LinearLayout>
 
@@ -56,7 +57,7 @@
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:ellipsize="marquee"
             android:fadingEdge="horizontal" />
-            
+
         <TextView android:id="@+android:id/summary"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e6fd538..3dacc61 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5180,6 +5180,8 @@
         <attr name="updatePeriodMillis" format="integer" />
         <!-- A resource id of a layout. -->
         <attr name="initialLayout" format="reference" />
+        <!-- A resource id of a layout. -->
+        <attr name="initialKeyguardLayout" format="reference" />
         <!-- A class name in the AppWidget's package to be launched to configure.
              If not supplied, then no activity will be launched. -->
         <attr name="configure" format="string" />
@@ -5190,12 +5192,26 @@
              by the widget's host. -->
         <attr name="autoAdvanceViewId" format="reference" />
         <!-- Optional parameter which indicates if and how this widget can be
-             resized. -->
+             resized. Supports combined values using | operator. -->
         <attr name="resizeMode" format="integer">
             <flag name="none" value="0x0" />
             <flag name="horizontal" value="0x1" />
             <flag name="vertical" value="0x2" />
         </attr>
+        <!-- Optional parameter which indicates where this widget can be shown,
+             ie. home screen, keyguard or both.
+             resized. Supports combined values using | operator. -->
+        <attr name="widgetCategory" format="integer">
+            <flag name="home_screen" value="0x1" />
+            <flag name="keyguard" value="0x2" />
+        </attr>
+        <!-- Optional parameter which indicates any feature(s) that this widget
+             supports. Supports combined values using | operator. -->
+        <attr name="widgetFeatures" format="integer">
+            <flag name="none" value="0x0" />
+            <flag name="clock" value="0x1" />
+            <flag name="status" value="0x2" />
+        </attr>
     </declare-styleable>
 
     <!-- =============================== -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bba2252..7895489 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -537,17 +537,18 @@
 
     <!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
          The N entries of this array define N + 1 control points as follows:
+         (1-based arrays)
 
-         Point 1:        LUX <= 0 (implicit)
-         Point 2:        0 < level[1] == LUX < level[2]
+         Point 1:            (0, value[1]):             lux <= 0
+         Point 2:     (level[1], value[2]):  0        < lux <= level[1]
+         Point 3:     (level[2], value[3]):  level[2] < lux <= level[3]
          ...
-         Point N:        level[N - 1] == LUX < level[N]
-         Point N + 1:    level[N] <= LUX < infinity
+         Point N+1: (level[N], value[N+1]):  level[N] < lux
 
          The control points must be strictly increasing.  Each control point
          corresponds to an entry in the brightness backlight values arrays.
          For example, if LUX == level[1] (first element of the levels array)
-         then the brightness will be determined by value[1] (first element
+         then the brightness will be determined by value[2] (second element
          of the brightness values array).
 
          Spline interpolation is used to determine the auto-brightness
@@ -923,5 +924,5 @@
     <bool name="config_syncstorageengine_masterSyncAutomatically">true</bool>
 
     <!--  Maximum number of supported users -->
-    <integer name="config_multiuserMaximumUsers">10</integer>
+    <integer name="config_multiuserMaximumUsers">1</integer>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 139715c..02bf710 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!-- This file defines the base public resources exported by the
      platform, which must always exist. -->
 
@@ -19,1776 +20,6 @@
      *************************************************************** -->
 <resources>
 
-  <!-- We don't want to publish private symbols in android.R as part of the
-       SDK.  Instead, put them here. -->
-  <private-symbols package="com.android.internal" />
-
-  <!-- Private symbols that we need to reference from framework code.  See
-       frameworks/base/core/res/MakeJavaSymbols.sed for how to easily generate
-       this.
-  -->
-  <java-symbol type="id" name="account_name" />
-  <java-symbol type="id" name="account_row_icon" />
-  <java-symbol type="id" name="account_row_text" />
-  <java-symbol type="id" name="account_type" />
-  <java-symbol type="id" name="action_bar" />
-  <java-symbol type="id" name="action_bar_container" />
-  <java-symbol type="id" name="action_bar_overlay_layout" />
-  <java-symbol type="id" name="action_bar_title" />
-  <java-symbol type="id" name="action_bar_subtitle" />
-  <java-symbol type="id" name="action_context_bar" />
-  <java-symbol type="id" name="action_menu_presenter" />
-  <java-symbol type="id" name="action_mode_close_button" />
-  <java-symbol type="id" name="activity_chooser_view_content" />
-  <java-symbol type="id" name="albumart" />
-  <java-symbol type="id" name="alertTitle" />
-  <java-symbol type="id" name="allow_button" />
-  <java-symbol type="id" name="alwaysUse" />
-  <java-symbol type="id" name="amPm" />
-  <java-symbol type="id" name="authtoken_type" />
-  <java-symbol type="id" name="back_button" />
-  <java-symbol type="id" name="btn_next" />
-  <java-symbol type="id" name="btn_play" />
-  <java-symbol type="id" name="btn_prev" />
-  <java-symbol type="id" name="button_bar" />
-  <java-symbol type="id" name="buttonPanel" />
-  <java-symbol type="id" name="by_common" />
-  <java-symbol type="id" name="by_org" />
-  <java-symbol type="id" name="by_org_unit" />
-  <java-symbol type="id" name="calendar_view" />
-  <java-symbol type="id" name="cancel" />
-  <java-symbol type="id" name="characterPicker" />
-  <java-symbol type="id" name="clearDefaultHint" />
-  <java-symbol type="id" name="contentPanel" />
-  <java-symbol type="id" name="customPanel" />
-  <java-symbol type="id" name="datePicker" />
-  <java-symbol type="id" name="day" />
-  <java-symbol type="id" name="day_names" />
-  <java-symbol type="id" name="decrement" />
-  <java-symbol type="id" name="default_activity_button" />
-  <java-symbol type="id" name="deny_button" />
-  <java-symbol type="id" name="description" />
-  <java-symbol type="id" name="divider" />
-  <java-symbol type="id" name="edit_query" />
-  <java-symbol type="id" name="edittext_container" />
-  <java-symbol type="id" name="enter_pin_section" />
-  <java-symbol type="id" name="expand_activities_button" />
-  <java-symbol type="id" name="expand_button" />
-  <java-symbol type="id" name="expand_button_divider" />
-  <java-symbol type="id" name="expires_on" />
-  <java-symbol type="id" name="find_next" />
-  <java-symbol type="id" name="find_prev" />
-  <java-symbol type="id" name="ffwd" />
-  <java-symbol type="id" name="fillInIntent" />
-  <java-symbol type="id" name="find" />
-  <java-symbol type="id" name="fullscreenArea" />
-  <java-symbol type="id" name="hard_keyboard_section" />
-  <java-symbol type="id" name="hard_keyboard_switch" />
-  <java-symbol type="id" name="headers" />
-  <java-symbol type="id" name="hour" />
-  <java-symbol type="id" name="icon" />
-  <java-symbol type="id" name="image" />
-  <java-symbol type="id" name="increment" />
-  <java-symbol type="id" name="internalEmpty" />
-  <java-symbol type="id" name="info" />
-  <java-symbol type="id" name="inputExtractAccessories" />
-  <java-symbol type="id" name="inputExtractAction" />
-  <java-symbol type="id" name="inputExtractEditButton" />
-  <java-symbol type="id" name="issued_on" />
-  <java-symbol type="id" name="left_icon" />
-  <java-symbol type="id" name="leftSpacer" />
-  <java-symbol type="id" name="line1" />
-  <java-symbol type="id" name="line3" />
-  <java-symbol type="id" name="list_footer" />
-  <java-symbol type="id" name="list_item" />
-  <java-symbol type="id" name="listContainer" />
-  <java-symbol type="id" name="locale" />
-  <java-symbol type="id" name="matches" />
-  <java-symbol type="id" name="mediacontroller_progress" />
-  <java-symbol type="id" name="minute" />
-  <java-symbol type="id" name="mode_normal" />
-  <java-symbol type="id" name="month" />
-  <java-symbol type="id" name="month_name" />
-  <java-symbol type="id" name="name" />
-  <java-symbol type="id" name="next" />
-  <java-symbol type="id" name="next_button" />
-  <java-symbol type="id" name="new_app_action" />
-  <java-symbol type="id" name="new_app_description" />
-  <java-symbol type="id" name="new_app_icon" />
-  <java-symbol type="id" name="no_permissions" />
-  <java-symbol type="id" name="numberpicker_input" />
-  <java-symbol type="id" name="old_app_action" />
-  <java-symbol type="id" name="old_app_description" />
-  <java-symbol type="id" name="old_app_icon" />
-  <java-symbol type="id" name="overlay_display_window_texture" />
-  <java-symbol type="id" name="overlay_display_window_title" />
-  <java-symbol type="id" name="package_label" />
-  <java-symbol type="id" name="packages_list" />
-  <java-symbol type="id" name="pause" />
-  <java-symbol type="id" name="show_more" />
-  <java-symbol type="id" name="perm_icon" />
-  <java-symbol type="id" name="show_more_icon" />
-  <java-symbol type="id" name="show_more_text" />
-  <java-symbol type="id" name="dangerous_perms_list" />
-  <java-symbol type="id" name="non_dangerous_perms_list" />
-  <java-symbol type="id" name="permission_group" />
-  <java-symbol type="id" name="permission_list" />
-  <java-symbol type="id" name="pickers" />
-  <java-symbol type="id" name="prefs" />
-  <java-symbol type="id" name="prefs_frame" />
-  <java-symbol type="id" name="prev" />
-  <java-symbol type="id" name="progress" />
-  <java-symbol type="id" name="progress_circular" />
-  <java-symbol type="id" name="progress_horizontal" />
-  <java-symbol type="id" name="progress_number" />
-  <java-symbol type="id" name="progress_percent" />
-  <java-symbol type="id" name="progressContainer" />
-  <java-symbol type="id" name="rew" />
-  <java-symbol type="id" name="rightSpacer" />
-  <java-symbol type="id" name="rowTypeId" />
-  <java-symbol type="id" name="scrollView" />
-  <java-symbol type="id" name="search_app_icon" />
-  <java-symbol type="id" name="search_badge" />
-  <java-symbol type="id" name="search_bar" />
-  <java-symbol type="id" name="search_button" />
-  <java-symbol type="id" name="search_close_btn" />
-  <java-symbol type="id" name="search_edit_frame" />
-  <java-symbol type="id" name="search_go_btn" />
-  <java-symbol type="id" name="search_mag_icon" />
-  <java-symbol type="id" name="search_plate" />
-  <java-symbol type="id" name="search_src_text" />
-  <java-symbol type="id" name="search_view" />
-  <java-symbol type="id" name="search_voice_btn" />
-  <java-symbol type="id" name="select_all" />
-  <java-symbol type="id" name="serial_number" />
-  <java-symbol type="id" name="seekbar" />
-  <java-symbol type="id" name="sha1_fingerprint" />
-  <java-symbol type="id" name="sha256_fingerprint" />
-  <java-symbol type="id" name="share" />
-  <java-symbol type="id" name="shortcut" />
-  <java-symbol type="id" name="skip_button" />
-  <java-symbol type="id" name="slider_group" />
-  <java-symbol type="id" name="split_action_bar" />
-  <java-symbol type="id" name="stream_icon" />
-  <java-symbol type="id" name="submit_area" />
-  <java-symbol type="id" name="switch_new" />
-  <java-symbol type="id" name="switch_old" />
-  <java-symbol type="id" name="switchWidget" />
-  <java-symbol type="id" name="text" />
-  <java-symbol type="id" name="time" />
-  <java-symbol type="id" name="time_current" />
-  <java-symbol type="id" name="timeDisplayBackground" />
-  <java-symbol type="id" name="timeDisplayForeground" />
-  <java-symbol type="id" name="titleDivider" />
-  <java-symbol type="id" name="titleDividerTop" />
-  <java-symbol type="id" name="timePicker" />
-  <java-symbol type="id" name="title_template" />
-  <java-symbol type="id" name="to_common" />
-  <java-symbol type="id" name="to_org" />
-  <java-symbol type="id" name="to_org_unit" />
-  <java-symbol type="id" name="top_action_bar" />
-  <java-symbol type="id" name="topPanel" />
-  <java-symbol type="id" name="up" />
-  <java-symbol type="id" name="value" />
-  <java-symbol type="id" name="visible_panel" />
-  <java-symbol type="id" name="websearch" />
-  <java-symbol type="id" name="wifi_p2p_wps_pin" />
-  <java-symbol type="id" name="year" />
-  <java-symbol type="id" name="zoomControls" />
-  <java-symbol type="id" name="zoomIn" />
-  <java-symbol type="id" name="zoomMagnify" />
-  <java-symbol type="id" name="zoomOut" />
-  <java-symbol type="id" name="actions" />
-  <java-symbol type="id" name="action0" />
-  <java-symbol type="id" name="action1" />
-  <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="id" name="inbox_text0" />
-  <java-symbol type="id" name="inbox_text1" />
-  <java-symbol type="id" name="inbox_text2" />
-  <java-symbol type="id" name="inbox_text3" />
-  <java-symbol type="id" name="inbox_text4" />
-  <java-symbol type="id" name="inbox_text5" />
-  <java-symbol type="id" name="inbox_text6" />
-  <java-symbol type="id" name="inbox_more" />
-  <java-symbol type="id" name="status_bar_latest_event_content" />
-  <java-symbol type="id" name="action_divider" />
-  <java-symbol type="id" name="overflow_divider" />
-
-  <java-symbol type="attr" name="actionModeShareDrawable" />
-  <java-symbol type="attr" name="alertDialogCenterButtons" />
-  <java-symbol type="attr" name="gestureOverlayViewStyle" />
-  <java-symbol type="attr" name="keyboardViewStyle" />
-  <java-symbol type="attr" name="numberPickerStyle" />
-  <java-symbol type="attr" name="pointerStyle" />
-  <java-symbol type="attr" name="preferenceFrameLayoutStyle" />
-  <java-symbol type="attr" name="searchDialogTheme" />
-  <java-symbol type="attr" name="searchViewSearchIcon" />
-  <java-symbol type="attr" name="stackViewStyle" />
-  <java-symbol type="attr" name="switchStyle" />
-  <java-symbol type="attr" name="textAppearanceAutoCorrectionSuggestion" />
-  <java-symbol type="attr" name="textAppearanceEasyCorrectSuggestion" />
-  <java-symbol type="attr" name="textAppearanceMisspelledSuggestion" />
-  <java-symbol type="attr" name="textColorSearchUrl" />
-  <java-symbol type="attr" name="timePickerStyle" />
-  <java-symbol type="attr" name="windowFixedWidthMajor" />
-  <java-symbol type="attr" name="windowFixedWidthMinor" />
-  <java-symbol type="attr" name="windowFixedHeightMajor" />
-  <java-symbol type="attr" name="windowFixedHeightMinor" />
-  <java-symbol type="attr" name="accessibilityFocusedDrawable"/>
-
-  <java-symbol type="bool" name="action_bar_embed_tabs" />
-  <java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" />
-  <java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" />
-  <java-symbol type="bool" name="config_allowActionMenuItemTextWithIcon" />
-  <java-symbol type="bool" name="config_bluetooth_adapter_quick_switch" />
-  <java-symbol type="bool" name="config_bluetooth_sco_off_call" />
-  <java-symbol type="bool" name="config_cellBroadcastAppLinks" />
-  <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
-  <java-symbol type="bool" name="config_enable_emergency_call_while_sim_locked" />
-  <java-symbol type="bool" name="config_enable_puk_unlock_screen" />
-  <java-symbol type="bool" name="config_mms_content_disposition_support" />
-  <java-symbol type="bool" name="config_showMenuShortcutsWhenKeyboardPresent" />
-  <java-symbol type="bool" name="config_sip_wifi_only" />
-  <java-symbol type="bool" name="config_sms_capable" />
-  <java-symbol type="bool" name="config_sms_utf8_support" />
-  <java-symbol type="bool" name="config_swipeDisambiguation" />
-  <java-symbol type="bool" name="config_syncstorageengine_masterSyncAutomatically" />
-  <java-symbol type="bool" name="config_telephony_use_own_number_for_voicemail" />
-  <java-symbol type="bool" name="config_ui_enableFadingMarquee" />
-  <java-symbol type="bool" name="config_use_strict_phone_number_comparation" />
-  <java-symbol type="bool" name="config_voice_capable" />
-  <java-symbol type="bool" name="preferences_prefer_dual_pane" />
-  <java-symbol type="bool" name="skip_restoring_network_selection" />
-  <java-symbol type="bool" name="split_action_bar_is_narrow" />
-  <java-symbol type="bool" name="config_useMasterVolume" />
-  <java-symbol type="bool" name="config_useVolumeKeySounds" />
-  <java-symbol type="bool" name="config_enableWallpaperService" />
-  <java-symbol type="bool" name="config_sendAudioBecomingNoisy" />
-  <java-symbol type="bool" name="config_enableScreenshotChord" />
-  <java-symbol type="bool" name="config_bluetooth_default_profiles" />
-
-  <java-symbol type="integer" name="config_cursorWindowSize" />
-  <java-symbol type="integer" name="config_longPressOnPowerBehavior" />
-  <java-symbol type="integer" name="config_max_pan_devices" />
-  <java-symbol type="integer" name="config_ntpTimeout" />
-  <java-symbol type="integer" name="config_wifi_framework_scan_interval" />
-  <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
-  <java-symbol type="integer" name="db_connection_pool_size" />
-  <java-symbol type="integer" name="db_journal_size_limit" />
-  <java-symbol type="integer" name="db_wal_autocheckpoint" />
-  <java-symbol type="integer" name="max_action_buttons" />
-  <java-symbol type="integer" name="config_wifi_driver_stop_delay" />
-  <java-symbol type="integer" name="config_soundEffectVolumeDb" />
-  <java-symbol type="integer" name="config_lockSoundVolumeDb" />
-  <java-symbol type="integer" name="config_multiuserMaximumUsers" />
-
-  <java-symbol type="color" name="tab_indicator_text_v4" />
-
-  <java-symbol type="dimen" name="config_prefDialogWidth" />
-  <java-symbol type="dimen" name="config_viewConfigurationTouchSlop" />
-  <java-symbol type="dimen" name="default_app_widget_padding_bottom" />
-  <java-symbol type="dimen" name="default_app_widget_padding_left" />
-  <java-symbol type="dimen" name="default_app_widget_padding_right" />
-  <java-symbol type="dimen" name="default_app_widget_padding_top" />
-  <java-symbol type="dimen" name="default_gap" />
-  <java-symbol type="dimen" name="dropdownitem_icon_width" />
-  <java-symbol type="dimen" name="dropdownitem_text_padding_left" />
-  <java-symbol type="dimen" name="fastscroll_overlay_size" />
-  <java-symbol type="dimen" name="fastscroll_thumb_height" />
-  <java-symbol type="dimen" name="fastscroll_thumb_width" />
-  <java-symbol type="dimen" name="fastscroll_thumb_width" />
-  <java-symbol type="dimen" name="password_keyboard_spacebar_vertical_correction" />
-  <java-symbol type="dimen" name="search_view_preferred_width" />
-  <java-symbol type="dimen" name="textview_error_popup_default_width" />
-  <java-symbol type="dimen" name="toast_y_offset" />
-  <java-symbol type="dimen" name="volume_panel_top" />
-  <java-symbol type="dimen" name="action_bar_stacked_max_height" />
-  <java-symbol type="dimen" name="action_bar_stacked_tab_max_width" />
-  <java-symbol type="dimen" name="notification_text_size" />
-  <java-symbol type="dimen" name="notification_title_text_size" />
-  <java-symbol type="dimen" name="notification_subtext_size" />
-
-  <java-symbol type="string" name="add_account_button_label" />
-  <java-symbol type="string" name="addToDictionary" />
-  <java-symbol type="string" name="action_bar_home_description" />
-  <java-symbol type="string" name="action_bar_up_description" />
-  <java-symbol type="string" name="delete" />
-  <java-symbol type="string" name="deleteText" />
-  <java-symbol type="string" name="ellipsis_two_dots" />
-  <java-symbol type="string" name="ellipsis" />
-  <java-symbol type="string" name="grant_permissions_header_text" />
-  <java-symbol type="string" name="list_delimeter" />
-  <java-symbol type="string" name="menu_delete_shortcut_label" />
-  <java-symbol type="string" name="menu_enter_shortcut_label" />
-  <java-symbol type="string" name="menu_space_shortcut_label" />
-  <java-symbol type="string" name="notification_title" />
-  <java-symbol type="string" name="permission_request_notification_with_subtitle" />
-  <java-symbol type="string" name="prepend_shortcut_label" />
-  <java-symbol type="string" name="replace" />
-  <java-symbol type="string" name="textSelectionCABTitle" />
-  <java-symbol type="string" name="BaMmi" />
-  <java-symbol type="string" name="CLIRDefaultOffNextCallOff" />
-  <java-symbol type="string" name="CLIRDefaultOffNextCallOn" />
-  <java-symbol type="string" name="CLIRDefaultOnNextCallOff" />
-  <java-symbol type="string" name="CLIRDefaultOnNextCallOn" />
-  <java-symbol type="string" name="CLIRPermanent" />
-  <java-symbol type="string" name="CfMmi" />
-  <java-symbol type="string" name="ClipMmi" />
-  <java-symbol type="string" name="ClirMmi" />
-  <java-symbol type="string" name="CwMmi" />
-  <java-symbol type="string" name="Midnight" />
-  <java-symbol type="string" name="Noon" />
-  <java-symbol type="string" name="PinMmi" />
-  <java-symbol type="string" name="PwdMmi" />
-  <java-symbol type="string" name="RestrictedChangedTitle" />
-  <java-symbol type="string" name="RestrictedOnAllVoice" />
-  <java-symbol type="string" name="RestrictedOnData" />
-  <java-symbol type="string" name="RestrictedOnEmergency" />
-  <java-symbol type="string" name="RestrictedOnNormal" />
-  <java-symbol type="string" name="SetupCallDefault" />
-  <java-symbol type="string" name="abbrev_month" />
-  <java-symbol type="string" name="abbrev_month_day" />
-  <java-symbol type="string" name="abbrev_month_day_year" />
-  <java-symbol type="string" name="abbrev_month_year" />
-  <java-symbol type="string" name="accept" />
-  <java-symbol type="string" name="activity_chooser_view_see_all" />
-  <java-symbol type="string" name="activitychooserview_choose_application" />
-  <java-symbol type="string" name="alternate_eri_file" />
-  <java-symbol type="string" name="alwaysUse" />
-  <java-symbol type="string" name="am" />
-  <java-symbol type="string" name="autofill_address_line_1_label_re" />
-  <java-symbol type="string" name="autofill_address_line_1_re" />
-  <java-symbol type="string" name="autofill_address_line_2_re" />
-  <java-symbol type="string" name="autofill_address_line_3_re" />
-  <java-symbol type="string" name="autofill_address_name_separator" />
-  <java-symbol type="string" name="autofill_address_summary_format" />
-  <java-symbol type="string" name="autofill_address_summary_name_format" />
-  <java-symbol type="string" name="autofill_address_summary_separator" />
-  <java-symbol type="string" name="autofill_address_type_same_as_re" />
-  <java-symbol type="string" name="autofill_address_type_use_my_re" />
-  <java-symbol type="string" name="autofill_area" />
-  <java-symbol type="string" name="autofill_area_code_notext_re" />
-  <java-symbol type="string" name="autofill_area_code_re" />
-  <java-symbol type="string" name="autofill_attention_ignored_re" />
-  <java-symbol type="string" name="autofill_billing_designator_re" />
-  <java-symbol type="string" name="autofill_card_cvc_re" />
-  <java-symbol type="string" name="autofill_card_ignored_re" />
-  <java-symbol type="string" name="autofill_card_number_re" />
-  <java-symbol type="string" name="autofill_city_re" />
-  <java-symbol type="string" name="autofill_company_re" />
-  <java-symbol type="string" name="autofill_country_code_re" />
-  <java-symbol type="string" name="autofill_country_re" />
-  <java-symbol type="string" name="autofill_county" />
-  <java-symbol type="string" name="autofill_department" />
-  <java-symbol type="string" name="autofill_district" />
-  <java-symbol type="string" name="autofill_email_re" />
-  <java-symbol type="string" name="autofill_emirate" />
-  <java-symbol type="string" name="autofill_expiration_date_re" />
-  <java-symbol type="string" name="autofill_expiration_month_re" />
-  <java-symbol type="string" name="autofill_fax_re" />
-  <java-symbol type="string" name="autofill_first_name_re" />
-  <java-symbol type="string" name="autofill_island" />
-  <java-symbol type="string" name="autofill_last_name_re" />
-  <java-symbol type="string" name="autofill_middle_initial_re" />
-  <java-symbol type="string" name="autofill_middle_name_re" />
-  <java-symbol type="string" name="autofill_name_on_card_contextual_re" />
-  <java-symbol type="string" name="autofill_name_on_card_re" />
-  <java-symbol type="string" name="autofill_name_re" />
-  <java-symbol type="string" name="autofill_name_specific_re" />
-  <java-symbol type="string" name="autofill_parish" />
-  <java-symbol type="string" name="autofill_phone_extension_re" />
-  <java-symbol type="string" name="autofill_phone_prefix_re" />
-  <java-symbol type="string" name="autofill_phone_prefix_separator_re" />
-  <java-symbol type="string" name="autofill_phone_re" />
-  <java-symbol type="string" name="autofill_phone_suffix_re" />
-  <java-symbol type="string" name="autofill_phone_suffix_separator_re" />
-  <java-symbol type="string" name="autofill_postal_code" />
-  <java-symbol type="string" name="autofill_prefecture" />
-  <java-symbol type="string" name="autofill_province" />
-  <java-symbol type="string" name="autofill_region_ignored_re" />
-  <java-symbol type="string" name="autofill_shipping_designator_re" />
-  <java-symbol type="string" name="autofill_state" />
-  <java-symbol type="string" name="autofill_state_re" />
-  <java-symbol type="string" name="autofill_this_form" />
-  <java-symbol type="string" name="autofill_username_re" />
-  <java-symbol type="string" name="autofill_zip_4_re" />
-  <java-symbol type="string" name="autofill_zip_code" />
-  <java-symbol type="string" name="autofill_zip_code_re" />
-  <java-symbol type="string" name="badPin" />
-  <java-symbol type="string" name="badPuk" />
-  <java-symbol type="string" name="byteShort" />
-  <java-symbol type="string" name="cfTemplateForwarded" />
-  <java-symbol type="string" name="cfTemplateForwardedTime" />
-  <java-symbol type="string" name="cfTemplateNotForwarded" />
-  <java-symbol type="string" name="cfTemplateRegistered" />
-  <java-symbol type="string" name="cfTemplateRegisteredTime" />
-  <java-symbol type="string" name="chooseActivity" />
-  <java-symbol type="string" name="config_default_dns_server" />
-  <java-symbol type="string" name="config_ethernet_iface_regex" />
-  <java-symbol type="string" name="config_ntpServer" />
-  <java-symbol type="string" name="config_tether_apndata" />
-  <java-symbol type="string" name="config_useragentprofile_url" />
-  <java-symbol type="string" name="config_wifi_p2p_device_type" />
-  <java-symbol type="string" name="contentServiceSync" />
-  <java-symbol type="string" name="contentServiceSyncNotificationTitle" />
-  <java-symbol type="string" name="contentServiceTooManyDeletesNotificationDesc" />
-  <java-symbol type="string" name="date1_date2" />
-  <java-symbol type="string" name="date1_time1_date2_time2" />
-  <java-symbol type="string" name="date_and_time" />
-  <java-symbol type="string" name="date_picker_decrement_day_button" />
-  <java-symbol type="string" name="date_picker_decrement_month_button" />
-  <java-symbol type="string" name="date_picker_decrement_year_button" />
-  <java-symbol type="string" name="date_picker_dialog_title" />
-  <java-symbol type="string" name="date_picker_increment_day_button" />
-  <java-symbol type="string" name="date_picker_increment_month_button" />
-  <java-symbol type="string" name="date_picker_increment_year_button" />
-  <java-symbol type="string" name="date_time" />
-  <java-symbol type="string" name="date_time_set" />
-  <java-symbol type="string" name="date_time_done" />
-  <java-symbol type="string" name="day_of_week_long_friday" />
-  <java-symbol type="string" name="day_of_week_long_monday" />
-  <java-symbol type="string" name="day_of_week_long_saturday" />
-  <java-symbol type="string" name="day_of_week_long_sunday" />
-  <java-symbol type="string" name="day_of_week_long_thursday" />
-  <java-symbol type="string" name="day_of_week_long_tuesday" />
-  <java-symbol type="string" name="day_of_week_long_wednesday" />
-  <java-symbol type="string" name="day_of_week_medium_friday" />
-  <java-symbol type="string" name="day_of_week_medium_monday" />
-  <java-symbol type="string" name="day_of_week_medium_saturday" />
-  <java-symbol type="string" name="day_of_week_medium_sunday" />
-  <java-symbol type="string" name="day_of_week_medium_thursday" />
-  <java-symbol type="string" name="day_of_week_medium_tuesday" />
-  <java-symbol type="string" name="day_of_week_medium_wednesday" />
-  <java-symbol type="string" name="day_of_week_short_friday" />
-  <java-symbol type="string" name="day_of_week_short_monday" />
-  <java-symbol type="string" name="day_of_week_short_saturday" />
-  <java-symbol type="string" name="day_of_week_short_sunday" />
-  <java-symbol type="string" name="day_of_week_short_thursday" />
-  <java-symbol type="string" name="day_of_week_short_tuesday" />
-  <java-symbol type="string" name="day_of_week_short_wednesday" />
-  <java-symbol type="string" name="day_of_week_shortest_friday" />
-  <java-symbol type="string" name="day_of_week_shortest_monday" />
-  <java-symbol type="string" name="day_of_week_shortest_saturday" />
-  <java-symbol type="string" name="day_of_week_shortest_sunday" />
-  <java-symbol type="string" name="day_of_week_shortest_thursday" />
-  <java-symbol type="string" name="day_of_week_shortest_tuesday" />
-  <java-symbol type="string" name="day_of_week_shortest_wednesday" />
-  <java-symbol type="string" name="db_default_journal_mode" />
-  <java-symbol type="string" name="db_default_sync_mode" />
-  <java-symbol type="string" name="db_wal_sync_mode" />
-  <java-symbol type="string" name="decline" />
-  <java-symbol type="string" name="default_text_encoding" />
-  <java-symbol type="string" name="description_target_unlock_tablet" />
-  <java-symbol type="string" name="display_manager_built_in_display_name" />
-  <java-symbol type="string" name="display_manager_hdmi_display_name" />
-  <java-symbol type="string" name="display_manager_overlay_display_name" />
-  <java-symbol type="string" name="display_manager_overlay_display_title" />
-  <java-symbol type="string" name="double_tap_toast" />
-  <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" />
-  <java-symbol type="string" name="elapsed_time_short_format_mm_ss" />
-  <java-symbol type="string" name="emailTypeCustom" />
-  <java-symbol type="string" name="emailTypeHome" />
-  <java-symbol type="string" name="emailTypeMobile" />
-  <java-symbol type="string" name="emailTypeOther" />
-  <java-symbol type="string" name="emailTypeWork" />
-  <java-symbol type="string" name="emergency_call_dialog_number_for_display" />
-  <java-symbol type="string" name="emergency_calls_only" />
-  <java-symbol type="string" name="eventTypeAnniversary" />
-  <java-symbol type="string" name="eventTypeBirthday" />
-  <java-symbol type="string" name="eventTypeCustom" />
-  <java-symbol type="string" name="eventTypeOther" />
-  <java-symbol type="string" name="extmedia_format_button_format" />
-  <java-symbol type="string" name="extmedia_format_message" />
-  <java-symbol type="string" name="extmedia_format_title" />
-  <java-symbol type="string" name="fileSizeSuffix" />
-  <java-symbol type="string" name="force_close" />
-  <java-symbol type="string" name="format_error" />
-  <java-symbol type="string" name="gadget_host_error_inflating" />
-  <java-symbol type="string" name="gigabyteShort" />
-  <java-symbol type="string" name="gpsNotifMessage" />
-  <java-symbol type="string" name="gpsNotifTicker" />
-  <java-symbol type="string" name="gpsNotifTitle" />
-  <java-symbol type="string" name="gpsVerifNo" />
-  <java-symbol type="string" name="gpsVerifYes" />
-  <java-symbol type="string" name="gsm_alphabet_default_charset" />
-  <java-symbol type="string" name="hour_ampm" />
-  <java-symbol type="string" name="hour_cap_ampm" />
-  <java-symbol type="string" name="hour_minute_24" />
-  <java-symbol type="string" name="hour_minute_ampm" />
-  <java-symbol type="string" name="hour_minute_cap_ampm" />
-  <java-symbol type="string" name="httpError" />
-  <java-symbol type="string" name="httpErrorAuth" />
-  <java-symbol type="string" name="httpErrorConnect" />
-  <java-symbol type="string" name="httpErrorFailedSslHandshake" />
-  <java-symbol type="string" name="httpErrorFile" />
-  <java-symbol type="string" name="httpErrorFileNotFound" />
-  <java-symbol type="string" name="httpErrorIO" />
-  <java-symbol type="string" name="httpErrorLookup" />
-  <java-symbol type="string" name="httpErrorOk" />
-  <java-symbol type="string" name="httpErrorProxyAuth" />
-  <java-symbol type="string" name="httpErrorRedirectLoop" />
-  <java-symbol type="string" name="httpErrorTimeout" />
-  <java-symbol type="string" name="httpErrorTooManyRequests" />
-  <java-symbol type="string" name="httpErrorUnsupportedAuthScheme" />
-  <java-symbol type="string" name="imProtocolAim" />
-  <java-symbol type="string" name="imProtocolCustom" />
-  <java-symbol type="string" name="imProtocolGoogleTalk" />
-  <java-symbol type="string" name="imProtocolIcq" />
-  <java-symbol type="string" name="imProtocolJabber" />
-  <java-symbol type="string" name="imProtocolMsn" />
-  <java-symbol type="string" name="imProtocolNetMeeting" />
-  <java-symbol type="string" name="imProtocolQq" />
-  <java-symbol type="string" name="imProtocolSkype" />
-  <java-symbol type="string" name="imProtocolYahoo" />
-  <java-symbol type="string" name="imTypeCustom" />
-  <java-symbol type="string" name="imTypeHome" />
-  <java-symbol type="string" name="imTypeOther" />
-  <java-symbol type="string" name="imTypeWork" />
-  <java-symbol type="string" name="ime_action_default" />
-  <java-symbol type="string" name="ime_action_done" />
-  <java-symbol type="string" name="ime_action_go" />
-  <java-symbol type="string" name="ime_action_next" />
-  <java-symbol type="string" name="ime_action_previous" />
-  <java-symbol type="string" name="ime_action_search" />
-  <java-symbol type="string" name="ime_action_send" />
-  <java-symbol type="string" name="invalidPin" />
-  <java-symbol type="string" name="js_dialog_before_unload" />
-  <java-symbol type="string" name="js_dialog_title" />
-  <java-symbol type="string" name="js_dialog_title_default" />
-  <java-symbol type="string" name="keyboard_headset_required_to_hear_password" />
-  <java-symbol type="string" name="keyboard_password_character_no_headset" />
-  <java-symbol type="string" name="keyboardview_keycode_alt" />
-  <java-symbol type="string" name="keyboardview_keycode_cancel" />
-  <java-symbol type="string" name="keyboardview_keycode_delete" />
-  <java-symbol type="string" name="keyboardview_keycode_done" />
-  <java-symbol type="string" name="keyboardview_keycode_enter" />
-  <java-symbol type="string" name="keyboardview_keycode_mode_change" />
-  <java-symbol type="string" name="keyboardview_keycode_shift" />
-  <java-symbol type="string" name="kilobyteShort" />
-  <java-symbol type="string" name="last_month" />
-  <java-symbol type="string" name="launchBrowserDefault" />
-  <java-symbol type="string" name="lockscreen_access_pattern_cell_added" />
-  <java-symbol type="string" name="lockscreen_access_pattern_cleared" />
-  <java-symbol type="string" name="lockscreen_access_pattern_detected" />
-  <java-symbol type="string" name="lockscreen_access_pattern_start" />
-  <java-symbol type="string" name="lockscreen_emergency_call" />
-  <java-symbol type="string" name="lockscreen_return_to_call" />
-  <java-symbol type="string" name="lockscreen_transport_pause_description" />
-  <java-symbol type="string" name="lockscreen_transport_play_description" />
-  <java-symbol type="string" name="lockscreen_transport_stop_description" />
-  <java-symbol type="string" name="low_memory" />
-  <java-symbol type="string" name="media_bad_removal" />
-  <java-symbol type="string" name="media_checking" />
-  <java-symbol type="string" name="media_removed" />
-  <java-symbol type="string" name="media_shared" />
-  <java-symbol type="string" name="media_unknown_state" />
-  <java-symbol type="string" name="megabyteShort" />
-  <java-symbol type="string" name="midnight" />
-  <java-symbol type="string" name="mismatchPin" />
-  <java-symbol type="string" name="mmiComplete" />
-  <java-symbol type="string" name="mmiError" />
-  <java-symbol type="string" name="mmiFdnError" />
-  <java-symbol type="string" name="month" />
-  <java-symbol type="string" name="month_day" />
-  <java-symbol type="string" name="month_day_year" />
-  <java-symbol type="string" name="month_long_april" />
-  <java-symbol type="string" name="month_long_august" />
-  <java-symbol type="string" name="month_long_december" />
-  <java-symbol type="string" name="month_long_february" />
-  <java-symbol type="string" name="month_long_january" />
-  <java-symbol type="string" name="month_long_july" />
-  <java-symbol type="string" name="month_long_june" />
-  <java-symbol type="string" name="month_long_march" />
-  <java-symbol type="string" name="month_long_may" />
-  <java-symbol type="string" name="month_long_november" />
-  <java-symbol type="string" name="month_long_october" />
-  <java-symbol type="string" name="month_long_september" />
-  <java-symbol type="string" name="month_long_standalone_april" />
-  <java-symbol type="string" name="month_long_standalone_august" />
-  <java-symbol type="string" name="month_long_standalone_december" />
-  <java-symbol type="string" name="month_long_standalone_february" />
-  <java-symbol type="string" name="month_long_standalone_january" />
-  <java-symbol type="string" name="month_long_standalone_july" />
-  <java-symbol type="string" name="month_long_standalone_june" />
-  <java-symbol type="string" name="month_long_standalone_march" />
-  <java-symbol type="string" name="month_long_standalone_may" />
-  <java-symbol type="string" name="month_long_standalone_november" />
-  <java-symbol type="string" name="month_long_standalone_october" />
-  <java-symbol type="string" name="month_long_standalone_september" />
-  <java-symbol type="string" name="month_medium_april" />
-  <java-symbol type="string" name="month_medium_august" />
-  <java-symbol type="string" name="month_medium_december" />
-  <java-symbol type="string" name="month_medium_february" />
-  <java-symbol type="string" name="month_medium_january" />
-  <java-symbol type="string" name="month_medium_july" />
-  <java-symbol type="string" name="month_medium_june" />
-  <java-symbol type="string" name="month_medium_march" />
-  <java-symbol type="string" name="month_medium_may" />
-  <java-symbol type="string" name="month_medium_november" />
-  <java-symbol type="string" name="month_medium_october" />
-  <java-symbol type="string" name="month_medium_september" />
-  <java-symbol type="string" name="month_shortest_april" />
-  <java-symbol type="string" name="month_shortest_august" />
-  <java-symbol type="string" name="month_shortest_december" />
-  <java-symbol type="string" name="month_shortest_february" />
-  <java-symbol type="string" name="month_shortest_january" />
-  <java-symbol type="string" name="month_shortest_july" />
-  <java-symbol type="string" name="month_shortest_june" />
-  <java-symbol type="string" name="month_shortest_march" />
-  <java-symbol type="string" name="month_shortest_may" />
-  <java-symbol type="string" name="month_shortest_november" />
-  <java-symbol type="string" name="month_shortest_october" />
-  <java-symbol type="string" name="month_shortest_september" />
-  <java-symbol type="string" name="month_year" />
-  <java-symbol type="string" name="more_item_label" />
-  <java-symbol type="string" name="needPuk" />
-  <java-symbol type="string" name="needPuk2" />
-  <java-symbol type="string" name="new_app_action" />
-  <java-symbol type="string" name="new_app_description" />
-  <java-symbol type="string" name="noApplications" />
-  <java-symbol type="string" name="no_file_chosen" />
-  <java-symbol type="string" name="no_matches" />
-  <java-symbol type="string" name="noon" />
-  <java-symbol type="string" name="number_picker_increment_scroll_action" />
-  <java-symbol type="string" name="number_picker_increment_scroll_mode" />
-  <java-symbol type="string" name="numeric_date" />
-  <java-symbol type="string" name="numeric_date_format" />
-  <java-symbol type="string" name="numeric_date_template" />
-  <java-symbol type="string" name="numeric_md1_md2" />
-  <java-symbol type="string" name="numeric_md1_time1_md2_time2" />
-  <java-symbol type="string" name="numeric_mdy1_mdy2" />
-  <java-symbol type="string" name="numeric_mdy1_time1_mdy2_time2" />
-  <java-symbol type="string" name="numeric_wday1_md1_time1_wday2_md2_time2" />
-  <java-symbol type="string" name="numeric_wday1_md1_wday2_md2" />
-  <java-symbol type="string" name="numeric_wday1_mdy1_time1_wday2_mdy2_time2" />
-  <java-symbol type="string" name="numeric_wday1_mdy1_wday2_mdy2" />
-  <java-symbol type="string" name="old_app_action" />
-  <java-symbol type="string" name="old_app_description" />
-  <java-symbol type="string" name="older" />
-  <java-symbol type="string" name="open_permission_deny" />
-  <java-symbol type="string" name="orgTypeCustom" />
-  <java-symbol type="string" name="orgTypeOther" />
-  <java-symbol type="string" name="orgTypeWork" />
-  <java-symbol type="string" name="passwordIncorrect" />
-  <java-symbol type="string" name="perms_description_app" />
-  <java-symbol type="string" name="perms_new_perm_prefix" />
-  <java-symbol type="string" name="perms_hide" />
-  <java-symbol type="string" name="perms_show_all" />
-  <java-symbol type="string" name="default_permission_group" />
-  <java-symbol type="string" name="permissions_format" />
-  <java-symbol type="string" name="petabyteShort" />
-  <java-symbol type="string" name="phoneTypeAssistant" />
-  <java-symbol type="string" name="phoneTypeCallback" />
-  <java-symbol type="string" name="phoneTypeCar" />
-  <java-symbol type="string" name="phoneTypeCompanyMain" />
-  <java-symbol type="string" name="phoneTypeCustom" />
-  <java-symbol type="string" name="phoneTypeFaxHome" />
-  <java-symbol type="string" name="phoneTypeFaxWork" />
-  <java-symbol type="string" name="phoneTypeHome" />
-  <java-symbol type="string" name="phoneTypeIsdn" />
-  <java-symbol type="string" name="phoneTypeMain" />
-  <java-symbol type="string" name="phoneTypeMms" />
-  <java-symbol type="string" name="phoneTypeMobile" />
-  <java-symbol type="string" name="phoneTypeOther" />
-  <java-symbol type="string" name="phoneTypeOtherFax" />
-  <java-symbol type="string" name="phoneTypePager" />
-  <java-symbol type="string" name="phoneTypeRadio" />
-  <java-symbol type="string" name="phoneTypeTelex" />
-  <java-symbol type="string" name="phoneTypeTtyTdd" />
-  <java-symbol type="string" name="phoneTypeWork" />
-  <java-symbol type="string" name="phoneTypeWorkMobile" />
-  <java-symbol type="string" name="phoneTypeWorkPager" />
-  <java-symbol type="string" name="pm" />
-  <java-symbol type="string" name="policydesc_disableCamera" />
-  <java-symbol type="string" name="policydesc_encryptedStorage" />
-  <java-symbol type="string" name="policydesc_expirePassword" />
-  <java-symbol type="string" name="policydesc_forceLock" />
-  <java-symbol type="string" name="policydesc_limitPassword" />
-  <java-symbol type="string" name="policydesc_resetPassword" />
-  <java-symbol type="string" name="policydesc_setGlobalProxy" />
-  <java-symbol type="string" name="policydesc_watchLogin" />
-  <java-symbol type="string" name="policydesc_wipeData" />
-  <java-symbol type="string" name="policydesc_disableKeyguardWidgets" />
-  <java-symbol type="string" name="policylab_disableCamera" />
-  <java-symbol type="string" name="policylab_encryptedStorage" />
-  <java-symbol type="string" name="policylab_expirePassword" />
-  <java-symbol type="string" name="policylab_forceLock" />
-  <java-symbol type="string" name="policylab_limitPassword" />
-  <java-symbol type="string" name="policylab_resetPassword" />
-  <java-symbol type="string" name="policylab_setGlobalProxy" />
-  <java-symbol type="string" name="policylab_watchLogin" />
-  <java-symbol type="string" name="policylab_wipeData" />
-  <java-symbol type="string" name="policylab_disableKeyguardWidgets" />
-  <java-symbol type="string" name="postalTypeCustom" />
-  <java-symbol type="string" name="postalTypeHome" />
-  <java-symbol type="string" name="postalTypeOther" />
-  <java-symbol type="string" name="postalTypeWork" />
-  <java-symbol type="string" name="power_off" />
-  <java-symbol type="string" name="preposition_for_date" />
-  <java-symbol type="string" name="preposition_for_time" />
-  <java-symbol type="string" name="progress_erasing" />
-  <java-symbol type="string" name="progress_unmounting" />
-  <java-symbol type="string" name="reboot_safemode_confirm" />
-  <java-symbol type="string" name="reboot_safemode_title" />
-  <java-symbol type="string" name="relationTypeAssistant" />
-  <java-symbol type="string" name="relationTypeBrother" />
-  <java-symbol type="string" name="relationTypeChild" />
-  <java-symbol type="string" name="relationTypeDomesticPartner" />
-  <java-symbol type="string" name="relationTypeFather" />
-  <java-symbol type="string" name="relationTypeFriend" />
-  <java-symbol type="string" name="relationTypeManager" />
-  <java-symbol type="string" name="relationTypeMother" />
-  <java-symbol type="string" name="relationTypeParent" />
-  <java-symbol type="string" name="relationTypePartner" />
-  <java-symbol type="string" name="relationTypeReferredBy" />
-  <java-symbol type="string" name="relationTypeRelative" />
-  <java-symbol type="string" name="relationTypeSister" />
-  <java-symbol type="string" name="relationTypeSpouse" />
-  <java-symbol type="string" name="relative_time" />
-  <java-symbol type="string" name="reset" />
-  <java-symbol type="string" name="ringtone_default" />
-  <java-symbol type="string" name="ringtone_default_with_actual" />
-  <java-symbol type="string" name="ringtone_picker_title" />
-  <java-symbol type="string" name="ringtone_silent" />
-  <java-symbol type="string" name="ringtone_unknown" />
-  <java-symbol type="string" name="roamingText0" />
-  <java-symbol type="string" name="roamingText1" />
-  <java-symbol type="string" name="roamingText10" />
-  <java-symbol type="string" name="roamingText11" />
-  <java-symbol type="string" name="roamingText12" />
-  <java-symbol type="string" name="roamingText2" />
-  <java-symbol type="string" name="roamingText3" />
-  <java-symbol type="string" name="roamingText4" />
-  <java-symbol type="string" name="roamingText5" />
-  <java-symbol type="string" name="roamingText6" />
-  <java-symbol type="string" name="roamingText7" />
-  <java-symbol type="string" name="roamingText8" />
-  <java-symbol type="string" name="roamingText9" />
-  <java-symbol type="string" name="roamingTextSearching" />
-  <java-symbol type="string" name="same_month_md1_md2" />
-  <java-symbol type="string" name="same_month_md1_time1_md2_time2" />
-  <java-symbol type="string" name="same_month_mdy1_mdy2" />
-  <java-symbol type="string" name="same_month_mdy1_time1_mdy2_time2" />
-  <java-symbol type="string" name="same_month_wday1_md1_time1_wday2_md2_time2" />
-  <java-symbol type="string" name="same_month_wday1_md1_wday2_md2" />
-  <java-symbol type="string" name="same_month_wday1_mdy1_time1_wday2_mdy2_time2" />
-  <java-symbol type="string" name="same_month_wday1_mdy1_wday2_mdy2" />
-  <java-symbol type="string" name="same_year_md1_md2" />
-  <java-symbol type="string" name="same_year_md1_time1_md2_time2" />
-  <java-symbol type="string" name="same_year_mdy1_mdy2" />
-  <java-symbol type="string" name="same_year_mdy1_time1_mdy2_time2" />
-  <java-symbol type="string" name="same_year_wday1_md1_time1_wday2_md2_time2" />
-  <java-symbol type="string" name="same_year_wday1_md1_wday2_md2" />
-  <java-symbol type="string" name="same_year_wday1_mdy1_time1_wday2_mdy2_time2" />
-  <java-symbol type="string" name="same_year_wday1_mdy1_wday2_mdy2" />
-  <java-symbol type="string" name="save_password_label" />
-  <java-symbol type="string" name="save_password_message" />
-  <java-symbol type="string" name="save_password_never" />
-  <java-symbol type="string" name="save_password_notnow" />
-  <java-symbol type="string" name="save_password_remember" />
-  <java-symbol type="string" name="sendText" />
-  <java-symbol type="string" name="sending" />
-  <java-symbol type="string" name="serviceClassData" />
-  <java-symbol type="string" name="serviceClassDataAsync" />
-  <java-symbol type="string" name="serviceClassDataSync" />
-  <java-symbol type="string" name="serviceClassFAX" />
-  <java-symbol type="string" name="serviceClassPAD" />
-  <java-symbol type="string" name="serviceClassPacket" />
-  <java-symbol type="string" name="serviceClassSMS" />
-  <java-symbol type="string" name="serviceClassVoice" />
-  <java-symbol type="string" name="serviceDisabled" />
-  <java-symbol type="string" name="serviceEnabled" />
-  <java-symbol type="string" name="serviceEnabledFor" />
-  <java-symbol type="string" name="serviceErased" />
-  <java-symbol type="string" name="serviceNotProvisioned" />
-  <java-symbol type="string" name="serviceRegistered" />
-  <java-symbol type="string" name="setup_autofill" />
-  <java-symbol type="string" name="share" />
-  <java-symbol type="string" name="shareactionprovider_share_with" />
-  <java-symbol type="string" name="shareactionprovider_share_with_application" />
-  <java-symbol type="string" name="short_format_month" />
-  <java-symbol type="string" name="shutdown_confirm" />
-  <java-symbol type="string" name="shutdown_confirm_question" />
-  <java-symbol type="string" name="shutdown_progress" />
-  <java-symbol type="string" name="sim_added_message" />
-  <java-symbol type="string" name="sim_added_title" />
-  <java-symbol type="string" name="sim_removed_message" />
-  <java-symbol type="string" name="sim_removed_title" />
-  <java-symbol type="string" name="sim_restart_button" />
-  <java-symbol type="string" name="sipAddressTypeCustom" />
-  <java-symbol type="string" name="sipAddressTypeHome" />
-  <java-symbol type="string" name="sipAddressTypeOther" />
-  <java-symbol type="string" name="sipAddressTypeWork" />
-  <java-symbol type="string" name="sms_control_message" />
-  <java-symbol type="string" name="sms_control_title" />
-  <java-symbol type="string" name="sms_control_no" />
-  <java-symbol type="string" name="sms_control_yes" />
-  <java-symbol type="string" name="sms_premium_short_code_confirm_message" />
-  <java-symbol type="string" name="sms_premium_short_code_confirm_title" />
-  <java-symbol type="string" name="sms_short_code_confirm_allow" />
-  <java-symbol type="string" name="sms_short_code_confirm_deny" />
-  <java-symbol type="string" name="sms_short_code_confirm_message" />
-  <java-symbol type="string" name="sms_short_code_confirm_report" />
-  <java-symbol type="string" name="sms_short_code_confirm_title" />
-  <java-symbol type="string" name="submit" />
-  <java-symbol type="string" name="sync_binding_label" />
-  <java-symbol type="string" name="sync_do_nothing" />
-  <java-symbol type="string" name="sync_really_delete" />
-  <java-symbol type="string" name="sync_too_many_deletes_desc" />
-  <java-symbol type="string" name="sync_undo_deletes" />
-  <java-symbol type="string" name="terabyteShort" />
-  <java-symbol type="string" name="text_copied" />
-  <java-symbol type="string" name="time1_time2" />
-  <java-symbol type="string" name="time_date" />
-  <java-symbol type="string" name="time_of_day" />
-  <java-symbol type="string" name="time_picker_decrement_hour_button" />
-  <java-symbol type="string" name="time_picker_decrement_minute_button" />
-  <java-symbol type="string" name="time_picker_decrement_set_am_button" />
-  <java-symbol type="string" name="time_picker_dialog_title" />
-  <java-symbol type="string" name="time_picker_increment_hour_button" />
-  <java-symbol type="string" name="time_picker_increment_minute_button" />
-  <java-symbol type="string" name="time_picker_increment_set_pm_button" />
-  <java-symbol type="string" name="time_picker_separator" />
-  <java-symbol type="string" name="time_wday" />
-  <java-symbol type="string" name="time_wday_date" />
-  <java-symbol type="string" name="today" />
-  <java-symbol type="string" name="tomorrow" />
-  <java-symbol type="string" name="twelve_hour_time_format" />
-  <java-symbol type="string" name="twenty_four_hour_time_format" />
-  <java-symbol type="string" name="upload_file" />
-  <java-symbol type="string" name="volume_alarm" />
-  <java-symbol type="string" name="volume_icon_description_bluetooth" />
-  <java-symbol type="string" name="volume_icon_description_incall" />
-  <java-symbol type="string" name="volume_icon_description_media" />
-  <java-symbol type="string" name="volume_icon_description_notification" />
-  <java-symbol type="string" name="volume_icon_description_ringer" />
-  <java-symbol type="string" name="wait" />
-  <java-symbol type="string" name="wday1_date1_time1_wday2_date2_time2" />
-  <java-symbol type="string" name="wday1_date1_wday2_date2" />
-  <java-symbol type="string" name="wday_date" />
-  <java-symbol type="string" name="web_user_agent" />
-  <java-symbol type="string" name="web_user_agent_target_content" />
-  <java-symbol type="string" name="webpage_unresponsive" />
-  <java-symbol type="string" name="whichApplication" />
-  <java-symbol type="string" name="wifi_available_sign_in" />
-  <java-symbol type="string" name="wifi_available_sign_in_detailed" />
-  <java-symbol type="string" name="wifi_p2p_dialog_title" />
-  <java-symbol type="string" name="wifi_p2p_enabled_notification_message" />
-  <java-symbol type="string" name="wifi_p2p_enabled_notification_title" />
-  <java-symbol type="string" name="wifi_p2p_failed_message" />
-  <java-symbol type="string" name="wifi_p2p_from_message" />
-  <java-symbol type="string" name="wifi_p2p_invitation_sent_title" />
-  <java-symbol type="string" name="wifi_p2p_invitation_to_connect_title" />
-  <java-symbol type="string" name="wifi_p2p_show_pin_message" />
-  <java-symbol type="string" name="wifi_p2p_to_message" />
-  <java-symbol type="string" name="wifi_p2p_turnon_message" />
-  <java-symbol type="string" name="wifi_tether_configure_ssid_default" />
-  <java-symbol type="string" name="wifi_watchdog_network_disabled" />
-  <java-symbol type="string" name="wifi_watchdog_network_disabled_detailed" />
-  <java-symbol type="string" name="yesterday" />
-  <java-symbol type="string" name="imei" />
-  <java-symbol type="string" name="meid" />
-  <java-symbol type="string" name="granularity_label_character" />
-  <java-symbol type="string" name="granularity_label_word" />
-  <java-symbol type="string" name="granularity_label_link" />
-  <java-symbol type="string" name="granularity_label_line" />
-  <java-symbol type="string" name="default_audio_route_name" />
-  <java-symbol type="string" name="default_audio_route_name_headphones" />
-  <java-symbol type="string" name="default_audio_route_name_dock_speakers" />
-  <java-symbol type="string" name="default_audio_route_name_hdmi" />
-  <java-symbol type="string" name="default_audio_route_category_name" />
-
-  <java-symbol type="plurals" name="abbrev_in_num_days" />
-  <java-symbol type="plurals" name="abbrev_in_num_hours" />
-  <java-symbol type="plurals" name="abbrev_in_num_minutes" />
-  <java-symbol type="plurals" name="abbrev_in_num_seconds" />
-  <java-symbol type="plurals" name="abbrev_num_days_ago" />
-  <java-symbol type="plurals" name="abbrev_num_hours_ago" />
-  <java-symbol type="plurals" name="abbrev_num_minutes_ago" />
-  <java-symbol type="plurals" name="abbrev_num_seconds_ago" />
-  <java-symbol type="plurals" name="in_num_days" />
-  <java-symbol type="plurals" name="in_num_hours" />
-  <java-symbol type="plurals" name="in_num_minutes" />
-  <java-symbol type="plurals" name="in_num_seconds" />
-  <java-symbol type="plurals" name="last_num_days" />
-  <java-symbol type="plurals" name="matches_found" />
-  <java-symbol type="plurals" name="num_days_ago" />
-  <java-symbol type="plurals" name="num_hours_ago" />
-  <java-symbol type="plurals" name="num_minutes_ago" />
-  <java-symbol type="plurals" name="num_seconds_ago" />
-
-  <java-symbol type="array" name="carrier_properties" />
-  <java-symbol type="array" name="config_data_usage_network_types" />
-  <java-symbol type="array" name="config_sms_enabled_locking_shift_tables" />
-  <java-symbol type="array" name="config_sms_enabled_single_shift_tables" />
-  <java-symbol type="array" name="config_twoDigitNumberPattern" />
-  <java-symbol type="array" name="networkAttributes" />
-  <java-symbol type="array" name="preloaded_color_state_lists" />
-  <java-symbol type="array" name="preloaded_drawables" />
-  <java-symbol type="array" name="special_locale_codes" />
-  <java-symbol type="array" name="special_locale_names" />
-  <java-symbol type="array" name="config_masterVolumeRamp" />
-  <java-symbol type="array" name="config_cdma_dun_supported_types" />
-
-  <java-symbol type="drawable" name="default_wallpaper" />
-  <java-symbol type="drawable" name="indicator_input_error" />
-  <java-symbol type="drawable" name="overscroll_edge" />
-  <java-symbol type="drawable" name="overscroll_glow" />
-  <java-symbol type="drawable" name="popup_bottom_dark" />
-  <java-symbol type="drawable" name="popup_bottom_bright" />
-  <java-symbol type="drawable" name="popup_bottom_medium" />
-  <java-symbol type="drawable" name="popup_center_dark" />
-  <java-symbol type="drawable" name="popup_center_bright" />
-  <java-symbol type="drawable" name="popup_full_dark" />
-  <java-symbol type="drawable" name="popup_full_bright" />
-  <java-symbol type="drawable" name="popup_top_dark" />
-  <java-symbol type="drawable" name="popup_top_bright" />
-  <java-symbol type="drawable" name="search_spinner" />
-  <java-symbol type="drawable" name="sym_app_on_sd_unavailable_icon" />
-  <java-symbol type="drawable" name="text_edit_side_paste_window" />
-  <java-symbol type="drawable" name="text_edit_paste_window" />
-  <java-symbol type="drawable" name="btn_check_off" />
-  <java-symbol type="drawable" name="btn_code_lock_default_holo" />
-  <java-symbol type="drawable" name="btn_code_lock_touched_holo" />
-  <java-symbol type="drawable" name="clock_dial" />
-  <java-symbol type="drawable" name="clock_hand_hour" />
-  <java-symbol type="drawable" name="clock_hand_minute" />
-  <java-symbol type="drawable" name="emo_im_angel" />
-  <java-symbol type="drawable" name="emo_im_cool" />
-  <java-symbol type="drawable" name="emo_im_crying" />
-  <java-symbol type="drawable" name="emo_im_embarrassed" />
-  <java-symbol type="drawable" name="emo_im_foot_in_mouth" />
-  <java-symbol type="drawable" name="emo_im_happy" />
-  <java-symbol type="drawable" name="emo_im_kissing" />
-  <java-symbol type="drawable" name="emo_im_laughing" />
-  <java-symbol type="drawable" name="emo_im_lips_are_sealed" />
-  <java-symbol type="drawable" name="emo_im_money_mouth" />
-  <java-symbol type="drawable" name="emo_im_sad" />
-  <java-symbol type="drawable" name="emo_im_surprised" />
-  <java-symbol type="drawable" name="emo_im_tongue_sticking_out" />
-  <java-symbol type="drawable" name="emo_im_undecided" />
-  <java-symbol type="drawable" name="emo_im_winking" />
-  <java-symbol type="drawable" name="emo_im_wtf" />
-  <java-symbol type="drawable" name="emo_im_yelling" />
-  <java-symbol type="drawable" name="expander_close_holo_dark" />
-  <java-symbol type="drawable" name="expander_open_holo_dark" />
-  <java-symbol type="drawable" name="ic_audio_alarm" />
-  <java-symbol type="drawable" name="ic_audio_alarm_mute" />
-  <java-symbol type="drawable" name="ic_audio_bt" />
-  <java-symbol type="drawable" name="ic_audio_bt_mute" />
-  <java-symbol type="drawable" name="ic_audio_notification" />
-  <java-symbol type="drawable" name="ic_audio_notification_mute" />
-  <java-symbol type="drawable" name="ic_audio_phone" />
-  <java-symbol type="drawable" name="ic_audio_ring_notif" />
-  <java-symbol type="drawable" name="ic_audio_ring_notif_mute" />
-  <java-symbol type="drawable" name="ic_audio_ring_notif_vibrate" />
-  <java-symbol type="drawable" name="ic_audio_vol" />
-  <java-symbol type="drawable" name="ic_audio_vol_mute" />
-  <java-symbol type="drawable" name="ic_bullet_key_permission" />
-  <java-symbol type="drawable" name="ic_contact_picture" />
-  <java-symbol type="drawable" name="ic_dialog_usb" />
-  <java-symbol type="drawable" name="ic_emergency" />
-  <java-symbol type="drawable" name="ic_media_stop" />
-  <java-symbol type="drawable" name="ic_text_dot" />
-  <java-symbol type="drawable" name="indicator_code_lock_drag_direction_green_up" />
-  <java-symbol type="drawable" name="indicator_code_lock_drag_direction_red_up" />
-  <java-symbol type="drawable" name="indicator_code_lock_point_area_default_holo" />
-  <java-symbol type="drawable" name="indicator_code_lock_point_area_green_holo" />
-  <java-symbol type="drawable" name="indicator_code_lock_point_area_red_holo" />
-  <java-symbol type="drawable" name="jog_dial_arrow_long_left_green" />
-  <java-symbol type="drawable" name="jog_dial_arrow_long_right_red" />
-  <java-symbol type="drawable" name="jog_dial_arrow_short_left_and_right" />
-  <java-symbol type="drawable" name="jog_dial_bg" />
-  <java-symbol type="drawable" name="jog_dial_dimple" />
-  <java-symbol type="drawable" name="jog_dial_dimple_dim" />
-  <java-symbol type="drawable" name="jog_tab_bar_left_generic" />
-  <java-symbol type="drawable" name="jog_tab_bar_right_generic" />
-  <java-symbol type="drawable" name="jog_tab_left_generic" />
-  <java-symbol type="drawable" name="jog_tab_right_generic" />
-  <java-symbol type="drawable" name="jog_tab_target_gray" />
-  <java-symbol type="drawable" name="picture_emergency" />
-  <java-symbol type="drawable" name="platlogo" />
-  <java-symbol type="drawable" name="platlogo_alt" />
-  <java-symbol type="drawable" name="stat_notify_sync_error" />
-  <java-symbol type="drawable" name="stat_notify_wifi_in_range" />
-  <java-symbol type="drawable" name="stat_sys_gps_on" />
-  <java-symbol type="drawable" name="stat_sys_tether_wifi" />
-  <java-symbol type="drawable" name="status_bar_background" />
-  <java-symbol type="drawable" name="sym_keyboard_shift" />
-  <java-symbol type="drawable" name="sym_keyboard_shift_locked" />
-  <java-symbol type="drawable" name="tab_bottom_left" />
-  <java-symbol type="drawable" name="tab_bottom_left_v4" />
-  <java-symbol type="drawable" name="tab_bottom_right" />
-  <java-symbol type="drawable" name="tab_bottom_right_v4" />
-  <java-symbol type="drawable" name="tab_indicator_v4" />
-  <java-symbol type="drawable" name="text_select_handle_left" />
-  <java-symbol type="drawable" name="text_select_handle_middle" />
-  <java-symbol type="drawable" name="text_select_handle_right" />
-  <java-symbol type="drawable" name="unknown_image" />
-  <java-symbol type="drawable" name="unlock_default" />
-  <java-symbol type="drawable" name="unlock_halo" />
-  <java-symbol type="drawable" name="unlock_ring" />
-  <java-symbol type="drawable" name="unlock_wave" />
-  <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_action_assist_generic" />
-  <java-symbol type="drawable" name="notification_bg" />
-  <java-symbol type="drawable" name="notification_bg_low" />
-  <java-symbol type="drawable" name="notification_template_icon_bg" />
-  <java-symbol type="drawable" name="notification_template_icon_low_bg" />
-  <java-symbol type="drawable" name="ic_lockscreen_unlock_phantom" />
-  <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
-  <java-symbol type="drawable" name="ic_media_route_disabled_holo_dark" />
-
-  <java-symbol type="layout" name="action_bar_home" />
-  <java-symbol type="layout" name="action_bar_title_item" />
-  <java-symbol type="layout" name="action_menu_item_layout" />
-  <java-symbol type="layout" name="action_menu_layout" />
-  <java-symbol type="layout" name="action_mode_close_item" />
-  <java-symbol type="layout" name="alert_dialog" />
-  <java-symbol type="layout" name="choose_account" />
-  <java-symbol type="layout" name="choose_account_row" />
-  <java-symbol type="layout" name="choose_account_type" />
-  <java-symbol type="layout" name="choose_type_and_account" />
-  <java-symbol type="layout" name="grant_credentials_permission" />
-  <java-symbol type="layout" name="number_picker" />
-  <java-symbol type="layout" name="permissions_package_list_item" />
-  <java-symbol type="layout" name="popup_menu_item_layout" />
-  <java-symbol type="layout" name="remote_views_adapter_default_loading_view" />
-  <java-symbol type="layout" name="search_bar" />
-  <java-symbol type="layout" name="search_dropdown_item_icons_2line" />
-  <java-symbol type="layout" name="search_view" />
-  <java-symbol type="layout" name="select_dialog" />
-  <java-symbol type="layout" name="simple_dropdown_hint" />
-  <java-symbol type="layout" name="status_bar_latest_event_content" />
-  <java-symbol type="layout" name="status_bar_latest_event_ticker" />
-  <java-symbol type="layout" name="status_bar_latest_event_ticker_large_icon" />
-  <java-symbol type="layout" name="text_edit_action_popup_text" />
-  <java-symbol type="layout" name="text_drag_thumbnail" />
-  <java-symbol type="layout" name="typing_filter" />
-  <java-symbol type="layout" name="activity_chooser_view" />
-  <java-symbol type="layout" name="activity_chooser_view_list_item" />
-  <java-symbol type="layout" name="activity_list" />
-  <java-symbol type="layout" name="activity_list_item_2" />
-  <java-symbol type="layout" name="alert_dialog_progress" />
-  <java-symbol type="layout" name="always_use_checkbox" />
-  <java-symbol type="layout" name="app_permission_item" />
-  <java-symbol type="layout" name="app_permission_item_old" />
-  <java-symbol type="layout" name="app_perms_summary" />
-  <java-symbol type="layout" name="calendar_view" />
-  <java-symbol type="layout" name="character_picker" />
-  <java-symbol type="layout" name="character_picker_button" />
-  <java-symbol type="layout" name="date_picker" />
-  <java-symbol type="layout" name="date_picker_dialog" />
-  <java-symbol type="layout" name="expanded_menu_layout" />
-  <java-symbol type="layout" name="fragment_bread_crumb_item" />
-  <java-symbol type="layout" name="fragment_bread_crumbs" />
-  <java-symbol type="layout" name="heavy_weight_switcher" />
-  <java-symbol type="layout" name="icon_menu_item_layout" />
-  <java-symbol type="layout" name="icon_menu_layout" />
-  <java-symbol type="layout" name="input_method" />
-  <java-symbol type="layout" name="input_method_extract_view" />
-  <java-symbol type="layout" name="input_method_switch_dialog_title" />
-  <java-symbol type="layout" name="js_prompt" />
-  <java-symbol type="layout" name="list_content_simple" />
-  <java-symbol type="layout" name="list_menu_item_checkbox" />
-  <java-symbol type="layout" name="list_menu_item_icon" />
-  <java-symbol type="layout" name="list_menu_item_layout" />
-  <java-symbol type="layout" name="list_menu_item_radio" />
-  <java-symbol type="layout" name="locale_picker_item" />
-  <java-symbol type="layout" name="media_controller" />
-  <java-symbol type="layout" name="overlay_display_window" />
-  <java-symbol type="layout" name="preference" />
-  <java-symbol type="layout" name="preference_header_item" />
-  <java-symbol type="layout" name="preference_list_content" />
-  <java-symbol type="layout" name="preference_list_content_single" />
-  <java-symbol type="layout" name="preference_list_fragment" />
-  <java-symbol type="layout" name="preference_widget_seekbar" />
-  <java-symbol type="layout" name="progress_dialog" />
-  <java-symbol type="layout" name="resolve_list_item" />
-  <java-symbol type="layout" name="seekbar_dialog" />
-  <java-symbol type="layout" name="select_dialog_singlechoice_holo" />
-  <java-symbol type="layout" name="ssl_certificate" />
-  <java-symbol type="layout" name="tab_content" />
-  <java-symbol type="layout" name="tab_indicator_holo" />
-  <java-symbol type="layout" name="textview_hint" />
-  <java-symbol type="layout" name="time_picker" />
-  <java-symbol type="layout" name="time_picker_dialog" />
-  <java-symbol type="layout" name="transient_notification" />
-  <java-symbol type="layout" name="volume_adjust" />
-  <java-symbol type="layout" name="volume_adjust_item" />
-  <java-symbol type="layout" name="web_text_view_dropdown" />
-  <java-symbol type="layout" name="webview_find" />
-  <java-symbol type="layout" name="webview_select_singlechoice" />
-  <java-symbol type="layout" name="wifi_p2p_dialog" />
-  <java-symbol type="layout" name="wifi_p2p_dialog_row" />
-  <java-symbol type="layout" name="zoom_container" />
-  <java-symbol type="layout" name="zoom_controls" />
-  <java-symbol type="layout" name="zoom_magnify" />
-  <java-symbol type="layout" name="notification_action" />
-  <java-symbol type="layout" name="notification_action_tombstone" />
-  <java-symbol type="layout" name="notification_intruder_content" />
-  <java-symbol type="layout" name="notification_template_base" />
-  <java-symbol type="layout" name="notification_template_big_base" />
-  <java-symbol type="layout" name="notification_template_big_picture" />
-  <java-symbol type="layout" name="notification_template_big_text" />
-  <java-symbol type="layout" name="notification_template_part_time" />
-  <java-symbol type="layout" name="notification_template_part_chronometer" />
-  <java-symbol type="layout" name="notification_template_inbox" />
-  <java-symbol type="layout" name="keyguard_multi_user_avatar" />
-  <java-symbol type="layout" name="keyguard_multi_user_selector_widget" />
-
-  <java-symbol type="anim" name="slide_in_child_bottom" />
-  <java-symbol type="anim" name="slide_in_right" />
-  <java-symbol type="anim" name="slide_out_left" />
-
-  <java-symbol type="menu" name="webview_copy" />
-  <java-symbol type="menu" name="webview_find" />
-
-  <java-symbol type="xml" name="password_kbd_qwerty" />
-  <java-symbol type="xml" name="autotext" />
-  <java-symbol type="xml" name="eri" />
-  <java-symbol type="xml" name="password_kbd_numeric" />
-  <java-symbol type="xml" name="password_kbd_qwerty_shifted" />
-  <java-symbol type="xml" name="password_kbd_symbols" />
-  <java-symbol type="xml" name="password_kbd_symbols_shift" />
-  <java-symbol type="xml" name="power_profile" />
-  <java-symbol type="xml" name="time_zones_by_country" />
-  <java-symbol type="xml" name="sms_short_codes" />
-
-  <java-symbol type="raw" name="accessibility_gestures" />
-  <java-symbol type="raw" name="incognito_mode_start_page" />
-  <java-symbol type="raw" name="loaderror" />
-  <java-symbol type="raw" name="nodomain" />
-
-  <java-symbol type="style" name="Animation.DropDownUp" />
-  <java-symbol type="style" name="Animation.DropDownDown" />
-  <java-symbol type="style" name="Animation.PopupWindow" />
-  <java-symbol type="style" name="Animation.TypingFilter" />
-  <java-symbol type="style" name="Animation.TypingFilterRestore" />
-  <java-symbol type="style" name="Animation.Dream" />
-  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.Alert" />
-  <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" />
-  <java-symbol type="style" name="Theme.Dialog.Alert" />
-  <java-symbol type="style" name="Theme.Holo.Dialog.Alert" />
-  <java-symbol type="style" name="Theme.Holo.Light.Dialog.Alert" />
-  <java-symbol type="style" name="ActiveWallpaperSettings" />
-  <java-symbol type="style" name="Animation.InputMethodFancy" />
-  <java-symbol type="style" name="Animation.Wallpaper" />
-  <java-symbol type="style" name="Animation.ZoomButtons" />
-  <java-symbol type="style" name="PreviewWallpaperSettings" />
-  <java-symbol type="style" name="TextAppearance.SlidingTabActive" />
-  <java-symbol type="style" name="TextAppearance.SlidingTabNormal" />
-  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.NoFrame" />
-  <java-symbol type="style" name="Theme.IconMenu" />
-  <java-symbol type="style" name="Theme.Panel.Volume" />
-
-  <java-symbol type="attr" name="mediaRouteButtonStyle" />
-  <java-symbol type="attr" name="externalRouteEnabledDrawable" />
-  <java-symbol type="id" name="extended_settings" />
-  <java-symbol type="id" name="check" />
-  <java-symbol type="id" name="volume_slider" />
-  <java-symbol type="id" name="volume_icon" />
-  <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
-  <java-symbol type="layout" name="media_route_chooser_layout" />
-  <java-symbol type="layout" name="media_route_list_item_top_header" />
-  <java-symbol type="layout" name="media_route_list_item_section_header" />
-  <java-symbol type="layout" name="media_route_list_item" />
-  <java-symbol type="layout" name="media_route_list_item_checkable" />
-  <java-symbol type="layout" name="media_route_list_item_collapse_group" />
-  <java-symbol type="string" name="bluetooth_a2dp_audio_route_name" />
-
-  <!-- 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="lock_screen_wallpaper_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="anim" name="keyguard_security_animate_in" />
-  <java-symbol type="anim" name="keyguard_security_animate_out" />
-  <java-symbol type="anim" name="keyguard_security_fade_in" />
-  <java-symbol type="anim" name="keyguard_security_fade_out" />
-  <java-symbol type="array" name="config_keyboardTapVibePattern" />
-  <java-symbol type="array" name="config_longPressVibePattern" />
-  <java-symbol type="array" name="config_safeModeDisabledVibePattern" />
-  <java-symbol type="array" name="config_safeModeEnabledVibePattern" />
-  <java-symbol type="array" name="config_virtualKeyVibePattern" />
-  <java-symbol type="array" name="lockscreen_targets_when_silent" />
-  <java-symbol type="array" name="lockscreen_targets_when_soundon" />
-  <java-symbol type="array" name="lockscreen_targets_with_camera" />
-  <java-symbol type="attr" name="actionModePopupWindowStyle" />
-  <java-symbol type="attr" name="dialogCustomTitleDecorLayout" />
-  <java-symbol type="attr" name="dialogTitleDecorLayout" />
-  <java-symbol type="attr" name="dialogTitleIconsDecorLayout" />
-  <java-symbol type="bool" name="config_allowAllRotations" />
-  <java-symbol type="bool" name="config_annoy_dianne" />
-  <java-symbol type="bool" name="config_carDockEnablesAccelerometer" />
-  <java-symbol type="bool" name="config_deskDockEnablesAccelerometer" />
-  <java-symbol type="bool" name="config_disableMenuKeyInLockScreen" />
-  <java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
-  <java-symbol type="bool" name="config_enableLockScreenRotation" />
-  <java-symbol type="bool" name="config_lidControlsSleep" />
-  <java-symbol type="bool" name="config_reverseDefaultRotation" />
-  <java-symbol type="bool" name="config_showNavigationBar" />
-  <java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
-  <java-symbol type="dimen" name="navigation_bar_height" />
-  <java-symbol type="dimen" name="navigation_bar_height_landscape" />
-  <java-symbol type="dimen" name="navigation_bar_width" />
-  <java-symbol type="dimen" name="status_bar_height" />
-  <java-symbol type="dimen" name="kg_widget_page_padding" />
-  <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" />
-  <java-symbol type="drawable" name="ic_jog_dial_vibrate_on" />
-  <java-symbol type="drawable" name="ic_lock_airplane_mode" />
-  <java-symbol type="drawable" name="ic_lock_airplane_mode_off" />
-  <java-symbol type="drawable" name="ic_menu_cc" />
-  <java-symbol type="drawable" name="jog_tab_bar_left_unlock" />
-  <java-symbol type="drawable" name="jog_tab_bar_right_sound_off" />
-  <java-symbol type="drawable" name="jog_tab_bar_right_sound_on" />
-  <java-symbol type="drawable" name="jog_tab_left_unlock" />
-  <java-symbol type="drawable" name="jog_tab_right_sound_off" />
-  <java-symbol type="drawable" name="jog_tab_right_sound_on" />
-  <java-symbol type="drawable" name="jog_tab_target_green" />
-  <java-symbol type="drawable" name="jog_tab_target_yellow" />
-  <java-symbol type="drawable" name="magnified_region_frame" />
-  <java-symbol type="drawable" name="menu_background" />
-  <java-symbol type="drawable" name="stat_sys_secure" />
-  <java-symbol type="drawable" name="kg_widget_overscroll_layer_left" />
-  <java-symbol type="drawable" name="kg_widget_overscroll_layer_right" />
-  <java-symbol type="id" name="action_mode_bar_stub" />
-  <java-symbol type="id" name="alarm_status" />
-  <java-symbol type="id" name="backspace" />
-  <java-symbol type="id" name="button0" />
-  <java-symbol type="id" name="button4" />
-  <java-symbol type="id" name="button5" />
-  <java-symbol type="id" name="button6" />
-  <java-symbol type="id" name="button7" />
-  <java-symbol type="id" name="carrier" />
-  <java-symbol type="id" name="date" />
-  <java-symbol type="id" name="eight" />
-  <java-symbol type="id" name="emergencyCallButton" />
-  <java-symbol type="id" name="face_unlock_area_view" />
-  <java-symbol type="id" name="five" />
-  <java-symbol type="id" name="forgotPatternButton" />
-  <java-symbol type="id" name="four" />
-  <java-symbol type="id" name="headerText" />
-  <java-symbol type="id" name="icon_menu_presenter" />
-  <java-symbol type="id" name="instructions" />
-  <java-symbol type="id" name="keyboard" />
-  <java-symbol type="id" name="list_menu_presenter" />
-  <java-symbol type="id" name="lockPattern" />
-  <java-symbol type="id" name="lock_screen" />
-  <java-symbol type="id" name="login" />
-  <java-symbol type="id" name="nine" />
-  <java-symbol type="id" name="no_applications_message" />
-  <java-symbol type="id" name="ok" />
-  <java-symbol type="id" name="one" />
-  <java-symbol type="id" name="option1" />
-  <java-symbol type="id" name="option2" />
-  <java-symbol type="id" name="option3" />
-  <java-symbol type="id" name="password" />
-  <java-symbol type="id" name="passwordEntry" />
-  <java-symbol type="id" name="pinDel" />
-  <java-symbol type="id" name="pinDisplay" />
-  <java-symbol type="id" name="owner_info" />
-  <java-symbol type="id" name="pukDel" />
-  <java-symbol type="id" name="pukDisplay" />
-  <java-symbol type="id" name="right_icon" />
-  <java-symbol type="id" name="seven" />
-  <java-symbol type="id" name="six" />
-  <java-symbol type="id" name="status" />
-  <java-symbol type="id" name="status1" />
-  <java-symbol type="id" name="switch_ime_button" />
-  <java-symbol type="id" name="three" />
-  <java-symbol type="id" name="title_container" />
-  <java-symbol type="id" name="topHeader" />
-  <java-symbol type="id" name="transport" />
-  <java-symbol type="id" name="transport_bg_protect" />
-  <java-symbol type="id" name="two" />
-  <java-symbol type="id" name="unlock_widget" />
-  <java-symbol type="id" name="zero" />
-  <java-symbol type="id" name="keyguard_message_area" />
-  <java-symbol type="id" name="keyguard_click_area" />
-  <java-symbol type="id" name="keyguard_selector_view" />
-  <java-symbol type="id" name="keyguard_pattern_view" />
-  <java-symbol type="id" name="keyguard_password_view" />
-  <java-symbol type="id" name="keyguard_face_unlock_view" />
-  <java-symbol type="id" name="keyguard_sim_pin_view" />
-  <java-symbol type="id" name="keyguard_sim_puk_view" />
-  <java-symbol type="id" name="keyguard_account_view" />
-  <java-symbol type="id" name="app_widget_container" />
-  <java-symbol type="id" name="view_flipper" />
-  <java-symbol type="id" name="emergency_call_button" />
-  <java-symbol type="id" name="keyguard_host_view" />
-  <java-symbol type="id" name="delete_button" />
-  <java-symbol type="id" name="lockPatternView" />
-  <java-symbol type="id" name="forgot_password_button" />
-  <java-symbol type="id" name="glow_pad_view" />
-  <java-symbol type="id" name="sim_pin_entry" />
-  <java-symbol type="id" name="delete_button" />
-  <java-symbol type="id" name="sim_puk_entry" />
-  <java-symbol type="id" name="sim_pin_entry" />
-  <java-symbol type="id" name="puk_delete_button" />
-  <java-symbol type="id" name="pin_delete_button" />
-  <java-symbol type="id" name="keyguard_user_avatar" />
-  <java-symbol type="id" name="keyguard_user_name" />
-  <java-symbol type="id" name="keyguard_active_user" />
-  <java-symbol type="id" name="keyguard_inactive_users" />
-  <java-symbol type="integer" name="config_carDockRotation" />
-  <java-symbol type="integer" name="config_defaultUiModeType" />
-  <java-symbol type="integer" name="config_deskDockRotation" />
-  <java-symbol type="integer" name="config_lidKeyboardAccessibility" />
-  <java-symbol type="integer" name="config_lidNavigationAccessibility" />
-  <java-symbol type="integer" name="config_lidOpenRotation" />
-  <java-symbol type="integer" name="config_longPressOnHomeBehavior" />
-  <java-symbol type="integer" name="kg_security_flip_duration" />
-  <java-symbol type="layout" name="global_actions_item" />
-  <java-symbol type="layout" name="global_actions_silent_mode" />
-  <java-symbol type="layout" name="keyguard_screen_glogin_unlock" />
-  <java-symbol type="layout" name="keyguard_screen_password_landscape" />
-  <java-symbol type="layout" name="keyguard_screen_password_portrait" />
-  <java-symbol type="layout" name="keyguard_screen_sim_pin_landscape" />
-  <java-symbol type="layout" name="keyguard_screen_sim_pin_portrait" />
-  <java-symbol type="layout" name="keyguard_screen_sim_puk_landscape" />
-  <java-symbol type="layout" name="keyguard_screen_sim_puk_portrait" />
-  <java-symbol type="layout" name="keyguard_screen_tab_unlock" />
-  <java-symbol type="layout" name="keyguard_screen_tab_unlock_land" />
-  <java-symbol type="layout" name="keyguard_screen_unlock_landscape" />
-  <java-symbol type="layout" name="keyguard_screen_unlock_portrait" />
-  <java-symbol type="layout" name="keyguard_selector_view" />
-  <java-symbol type="layout" name="keyguard_pattern_view" />
-  <java-symbol type="layout" name="keyguard_password_view" />
-  <java-symbol type="layout" name="keyguard_face_unlock_view" />
-  <java-symbol type="layout" name="keyguard_sim_pin_view" />
-  <java-symbol type="layout" name="keyguard_sim_puk_view" />
-  <java-symbol type="layout" name="keyguard_account_view" />
-  <java-symbol type="layout" name="recent_apps_dialog" />
-  <java-symbol type="layout" name="screen_action_bar" />
-  <java-symbol type="layout" name="screen_action_bar_overlay" />
-  <java-symbol type="layout" name="screen_custom_title" />
-  <java-symbol type="layout" name="screen_progress" />
-  <java-symbol type="layout" name="screen_simple" />
-  <java-symbol type="layout" name="screen_simple_overlay_action_mode" />
-  <java-symbol type="layout" name="screen_title" />
-  <java-symbol type="layout" name="screen_title_icons" />
-  <java-symbol type="layout" name="keyguard_host_view" />
-  <java-symbol type="string" name="abbrev_wday_month_day_no_year" />
-  <java-symbol type="string" name="android_upgrading_title" />
-  <java-symbol type="string" name="bugreport_title" />
-  <java-symbol type="string" name="bugreport_message" />
-  <java-symbol type="string" name="faceunlock_multiple_failures" />
-  <java-symbol type="string" name="global_action_power_off" />
-  <java-symbol type="string" name="global_actions_airplane_mode_off_status" />
-  <java-symbol type="string" name="global_actions_airplane_mode_on_status" />
-  <java-symbol type="string" name="global_actions_toggle_airplane_mode" />
-  <java-symbol type="string" name="global_action_bug_report" />
-  <java-symbol type="string" name="global_action_silent_mode_off_status" />
-  <java-symbol type="string" name="global_action_silent_mode_on_status" />
-  <java-symbol type="string" name="global_action_toggle_silent_mode" />
-  <java-symbol type="string" name="invalidPuk" />
-  <java-symbol type="string" name="keyguard_password_enter_pin_code" />
-  <java-symbol type="string" name="keyguard_password_enter_puk_code" />
-  <java-symbol type="string" name="keyguard_password_wrong_pin_code" />
-  <java-symbol type="string" name="lockscreen_carrier_default" />
-  <java-symbol type="string" name="lockscreen_charged" />
-  <java-symbol type="string" name="lockscreen_failed_attempts_almost_at_wipe" />
-  <java-symbol type="string" name="lockscreen_failed_attempts_almost_glogin" />
-  <java-symbol type="string" name="lockscreen_failed_attempts_now_wiping" />
-  <java-symbol type="string" name="lockscreen_forgot_pattern_button_text" />
-  <java-symbol type="string" name="lockscreen_glogin_checking_password" />
-  <java-symbol type="string" name="lockscreen_glogin_forgot_pattern" />
-  <java-symbol type="string" name="lockscreen_glogin_invalid_input" />
-  <java-symbol type="string" name="lockscreen_glogin_too_many_attempts" />
-  <java-symbol type="string" name="lockscreen_instructions_when_pattern_disabled" />
-  <java-symbol type="string" name="lockscreen_low_battery" />
-  <java-symbol type="string" name="lockscreen_missing_sim_instructions" />
-  <java-symbol type="string" name="lockscreen_missing_sim_instructions_long" />
-  <java-symbol type="string" name="lockscreen_missing_sim_message_short" />
-  <java-symbol type="string" name="lockscreen_network_locked_message" />
-  <java-symbol type="string" name="lockscreen_password_wrong" />
-  <java-symbol type="string" name="lockscreen_pattern_instructions" />
-  <java-symbol type="string" name="lockscreen_pattern_wrong" />
-  <java-symbol type="string" name="lockscreen_permanent_disabled_sim_message_short" />
-  <java-symbol type="string" name="lockscreen_permanent_disabled_sim_instructions" />
-  <java-symbol type="string" name="lockscreen_plugged_in" />
-  <java-symbol type="string" name="lockscreen_sim_locked_message" />
-  <java-symbol type="string" name="lockscreen_sim_puk_locked_message" />
-  <java-symbol type="string" name="lockscreen_sim_unlock_progress_dialog_message" />
-  <java-symbol type="string" name="lockscreen_sound_off_label" />
-  <java-symbol type="string" name="lockscreen_sound_on_label" />
-  <java-symbol type="string" name="lockscreen_too_many_failed_attempts_countdown" />
-  <java-symbol type="string" name="lockscreen_too_many_failed_attempts_dialog_message" />
-  <java-symbol type="string" name="lockscreen_too_many_failed_password_attempts_dialog_message" />
-  <java-symbol type="string" name="lockscreen_too_many_failed_pin_attempts_dialog_message" />
-  <java-symbol type="string" name="lockscreen_unlock_label" />
-  <java-symbol type="string" name="status_bar_device_locked" />
-  <java-symbol type="style" name="Animation.LockScreen" />
-  <java-symbol type="style" name="Theme.Dialog.RecentApplications" />
-  <java-symbol type="style" name="Theme.ExpandedMenu" />
-  <java-symbol type="string" name="kg_emergency_call_label" />
-  <java-symbol type="string" name="kg_forgot_pattern_button_text" />
-  <java-symbol type="string" name="kg_wrong_pattern" />
-  <java-symbol type="string" name="kg_wrong_password" />
-  <java-symbol type="string" name="kg_wrong_pin" />
-  <java-symbol type="string" name="kg_too_many_failed_attempts_countdown" />
-  <java-symbol type="string" name="kg_pattern_instructions" />
-  <java-symbol type="string" name="kg_sim_pin_instructions" />
-  <java-symbol type="string" name="kg_pin_instructions" />
-  <java-symbol type="string" name="kg_password_instructions" />
-  <java-symbol type="string" name="kg_puk_enter_puk_hint" />
-  <java-symbol type="string" name="kg_puk_enter_pin_hint" />
-  <java-symbol type="string" name="kg_sim_unlock_progress_dialog_message" />
-  <java-symbol type="string" name="kg_password_wrong_pin_code" />
-  <java-symbol type="string" name="kg_invalid_sim_pin_hint" />
-  <java-symbol type="string" name="kg_invalid_sim_puk_hint" />
-  <java-symbol type="string" name="kg_sim_puk_recovery_hint" />
-  <java-symbol type="string" name="kg_invalid_puk" />
-  <java-symbol type="string" name="kg_login_too_many_attempts" />
-  <java-symbol type="string" name="kg_login_instructions" />
-  <java-symbol type="string" name="kg_login_username_hint" />
-  <java-symbol type="string" name="kg_login_password_hint" />
-  <java-symbol type="string" name="kg_login_submit_button" />
-  <java-symbol type="string" name="kg_login_invalid_input" />
-  <java-symbol type="string" name="kg_login_account_recovery_hint" />
-  <java-symbol type="string" name="kg_login_checking_password" />
-  <java-symbol type="string" name="kg_too_many_failed_pin_attempts_dialog_message" />
-  <java-symbol type="string" name="kg_too_many_failed_pattern_attempts_dialog_message" />
-  <java-symbol type="string" name="kg_too_many_failed_password_attempts_dialog_message" />
-  <java-symbol type="string" name="kg_failed_attempts_almost_at_wipe" />
-  <java-symbol type="string" name="kg_failed_attempts_now_wiping" />
-  <java-symbol type="string" name="kg_failed_attempts_almost_at_login" />
-
-  <!-- From services -->
-  <java-symbol type="anim" name="screen_rotate_0_enter" />
-  <java-symbol type="anim" name="screen_rotate_0_exit" />
-  <java-symbol type="anim" name="screen_rotate_0_frame" />
-  <java-symbol type="anim" name="screen_rotate_180_enter" />
-  <java-symbol type="anim" name="screen_rotate_180_exit" />
-  <java-symbol type="anim" name="screen_rotate_180_frame" />
-  <java-symbol type="anim" name="screen_rotate_finish_enter" />
-  <java-symbol type="anim" name="screen_rotate_finish_exit" />
-  <java-symbol type="anim" name="screen_rotate_finish_frame" />
-  <java-symbol type="anim" name="screen_rotate_minus_90_enter" />
-  <java-symbol type="anim" name="screen_rotate_minus_90_exit" />
-  <java-symbol type="anim" name="screen_rotate_minus_90_frame" />
-  <java-symbol type="anim" name="screen_rotate_plus_90_enter" />
-  <java-symbol type="anim" name="screen_rotate_plus_90_exit" />
-  <java-symbol type="anim" name="screen_rotate_plus_90_frame" />
-  <java-symbol type="anim" name="screen_rotate_start_enter" />
-  <java-symbol type="anim" name="screen_rotate_start_exit" />
-  <java-symbol type="anim" name="screen_rotate_start_frame" />
-  <java-symbol type="anim" name="window_move_from_decor" />
-  <java-symbol type="array" name="config_autoBrightnessButtonBacklightValues" />
-  <java-symbol type="array" name="config_autoBrightnessKeyboardBacklightValues" />
-  <java-symbol type="array" name="config_autoBrightnessLcdBacklightValues" />
-  <java-symbol type="array" name="config_autoBrightnessLevels" />
-  <java-symbol type="array" name="config_protectedNetworks" />
-  <java-symbol type="array" name="config_statusBarIcons" />
-  <java-symbol type="array" name="config_tether_bluetooth_regexs" />
-  <java-symbol type="array" name="config_tether_dhcp_range" />
-  <java-symbol type="array" name="config_tether_upstream_types" />
-  <java-symbol type="array" name="config_tether_usb_regexs" />
-  <java-symbol type="array" name="config_tether_wifi_regexs" />
-  <java-symbol type="array" name="config_usbHostBlacklist" />
-  <java-symbol type="array" name="config_serialPorts" />
-  <java-symbol type="array" name="radioAttributes" />
-  <java-symbol type="array" name="config_oemUsbModeOverride" />
-  <java-symbol type="array" name="config_locationProviderPackageNames" />
-  <java-symbol type="array" name="config_overlay_locationProviderPackageNames" />
-  <java-symbol type="bool" name="config_animateScreenLights" />
-  <java-symbol type="bool" name="config_automatic_brightness_available" />
-  <java-symbol type="bool" name="config_sf_limitedAlpha" />
-  <java-symbol type="bool" name="config_unplugTurnsOnScreen" />
-  <java-symbol type="bool" name="config_wifi_background_scan_support" />
-  <java-symbol type="bool" name="config_wifi_dual_band_support" />
-  <java-symbol type="bool" name="config_wimaxEnabled" />
-  <java-symbol type="bool" name="show_ongoing_ime_switcher" />
-  <java-symbol type="color" name="config_defaultNotificationColor" />
-  <java-symbol type="drawable" name="ic_notification_ime_default" />
-  <java-symbol type="drawable" name="stat_notify_car_mode" />
-  <java-symbol type="drawable" name="stat_notify_disabled" />
-  <java-symbol type="drawable" name="stat_notify_disk_full" />
-  <java-symbol type="drawable" name="stat_sys_adb" />
-  <java-symbol type="drawable" name="stat_sys_battery" />
-  <java-symbol type="drawable" name="stat_sys_battery_charge" />
-  <java-symbol type="drawable" name="stat_sys_battery_unknown" />
-  <java-symbol type="drawable" name="stat_sys_data_usb" />
-  <java-symbol type="drawable" name="stat_sys_tether_bluetooth" />
-  <java-symbol type="drawable" name="stat_sys_tether_general" />
-  <java-symbol type="drawable" name="stat_sys_tether_usb" />
-  <java-symbol type="drawable" name="stat_sys_throttled" />
-  <java-symbol type="drawable" name="vpn_connected" />
-  <java-symbol type="drawable" name="vpn_disconnected" />
-  <java-symbol type="id" name="ask_checkbox" />
-  <java-symbol type="id" name="compat_checkbox" />
-  <java-symbol type="id" name="original_app_icon" />
-  <java-symbol type="id" name="original_message" />
-  <java-symbol type="id" name="radio" />
-  <java-symbol type="id" name="reask_hint" />
-  <java-symbol type="id" name="replace_app_icon" />
-  <java-symbol type="id" name="replace_message" />
-  <java-symbol type="fraction" name="config_dimBehindFadeDuration" />
-  <java-symbol type="integer" name="config_carDockKeepsScreenOn" />
-  <java-symbol type="integer" name="config_criticalBatteryWarningLevel" />
-  <java-symbol type="integer" name="config_datause_notification_type" />
-  <java-symbol type="integer" name="config_datause_polling_period_sec" />
-  <java-symbol type="integer" name="config_datause_threshold_bytes" />
-  <java-symbol type="integer" name="config_datause_throttle_kbitsps" />
-  <java-symbol type="integer" name="config_defaultNotificationLedOff" />
-  <java-symbol type="integer" name="config_defaultNotificationLedOn" />
-  <java-symbol type="integer" name="config_deskDockKeepsScreenOn" />
-  <java-symbol type="integer" name="config_lightSensorWarmupTime" />
-  <java-symbol type="integer" name="config_lowBatteryCloseWarningLevel" />
-  <java-symbol type="integer" name="config_lowBatteryWarningLevel" />
-  <java-symbol type="integer" name="config_networkPolicyDefaultWarning" />
-  <java-symbol type="integer" name="config_networkTransitionTimeout" />
-  <java-symbol type="integer" name="config_notificationsBatteryFullARGB" />
-  <java-symbol type="integer" name="config_notificationsBatteryLedOff" />
-  <java-symbol type="integer" name="config_notificationsBatteryLedOn" />
-  <java-symbol type="integer" name="config_notificationsBatteryLowARGB" />
-  <java-symbol type="integer" name="config_notificationsBatteryMediumARGB" />
-  <java-symbol type="integer" name="config_radioScanningTimeout" />
-  <java-symbol type="integer" name="config_screenBrightnessSettingMinimum" />
-  <java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
-  <java-symbol type="integer" name="config_screenBrightnessSettingDefault" />
-  <java-symbol type="integer" name="config_screenBrightnessDim" />
-  <java-symbol type="integer" name="config_shutdownBatteryTemperature" />
-  <java-symbol type="integer" name="config_virtualKeyQuietTimeMillis" />
-  <java-symbol type="layout" name="am_compat_mode_dialog" />
-  <java-symbol type="layout" name="launch_warning" />
-  <java-symbol type="layout" name="safe_mode" />
-  <java-symbol type="layout" name="simple_list_item_2_single_choice" />
-  <java-symbol type="plurals" name="wifi_available" />
-  <java-symbol type="plurals" name="wifi_available_detailed" />
-  <java-symbol type="string" name="accessibility_binding_label" />
-  <java-symbol type="string" name="adb_active_notification_message" />
-  <java-symbol type="string" name="adb_active_notification_title" />
-  <java-symbol type="string" name="aerr_application" />
-  <java-symbol type="string" name="aerr_process" />
-  <java-symbol type="string" name="aerr_title" />
-  <java-symbol type="string" name="android_upgrading_apk" />
-  <java-symbol type="string" name="android_upgrading_complete" />
-  <java-symbol type="string" name="android_upgrading_starting_apps" />
-  <java-symbol type="string" name="anr_activity_application" />
-  <java-symbol type="string" name="anr_activity_process" />
-  <java-symbol type="string" name="anr_application_process" />
-  <java-symbol type="string" name="anr_process" />
-  <java-symbol type="string" name="anr_title" />
-  <java-symbol type="string" name="car_mode_disable_notification_message" />
-  <java-symbol type="string" name="car_mode_disable_notification_title" />
-  <java-symbol type="string" name="chooser_wallpaper" />
-  <java-symbol type="string" name="config_datause_iface" />
-  <java-symbol type="string" name="config_wimaxManagerClassname" />
-  <java-symbol type="string" name="config_wimaxNativeLibLocation" />
-  <java-symbol type="string" name="config_wimaxServiceClassname" />
-  <java-symbol type="string" name="config_wimaxServiceJarLocation" />
-  <java-symbol type="string" name="config_wimaxStateTrackerClassname" />
-  <java-symbol type="string" name="configure_input_methods" />
-  <java-symbol type="string" name="data_usage_3g_limit_snoozed_title" />
-  <java-symbol type="string" name="data_usage_3g_limit_title" />
-  <java-symbol type="string" name="data_usage_4g_limit_snoozed_title" />
-  <java-symbol type="string" name="data_usage_4g_limit_title" />
-  <java-symbol type="string" name="data_usage_limit_body" />
-  <java-symbol type="string" name="data_usage_limit_snoozed_body" />
-  <java-symbol type="string" name="data_usage_mobile_limit_snoozed_title" />
-  <java-symbol type="string" name="data_usage_mobile_limit_title" />
-  <java-symbol type="string" name="data_usage_restricted_body" />
-  <java-symbol type="string" name="data_usage_restricted_title" />
-  <java-symbol type="string" name="data_usage_warning_body" />
-  <java-symbol type="string" name="data_usage_warning_title" />
-  <java-symbol type="string" name="data_usage_wifi_limit_snoozed_title" />
-  <java-symbol type="string" name="data_usage_wifi_limit_title" />
-  <java-symbol type="string" name="default_wallpaper_component" />
-  <java-symbol type="string" name="dlg_ok" />
-  <java-symbol type="string" name="factorytest_failed" />
-  <java-symbol type="string" name="factorytest_no_action" />
-  <java-symbol type="string" name="factorytest_not_system" />
-  <java-symbol type="string" name="factorytest_reboot" />
-  <java-symbol type="string" name="hardware" />
-  <java-symbol type="string" name="heavy_weight_notification" />
-  <java-symbol type="string" name="heavy_weight_notification_detail" />
-  <java-symbol type="string" name="input_method_binding_label" />
-  <java-symbol type="string" name="launch_warning_original" />
-  <java-symbol type="string" name="launch_warning_replace" />
-  <java-symbol type="string" name="launch_warning_title" />
-  <java-symbol type="string" name="low_internal_storage_view_text" />
-  <java-symbol type="string" name="low_internal_storage_view_title" />
-  <java-symbol type="string" name="report" />
-  <java-symbol type="string" name="select_input_method" />
-  <java-symbol type="string" name="select_keyboard_layout_notification_title" />
-  <java-symbol type="string" name="select_keyboard_layout_notification_message" />
-  <java-symbol type="string" name="smv_application" />
-  <java-symbol type="string" name="smv_process" />
-  <java-symbol type="string" name="tethered_notification_message" />
-  <java-symbol type="string" name="tethered_notification_title" />
-  <java-symbol type="string" name="throttle_warning_notification_message" />
-  <java-symbol type="string" name="throttle_warning_notification_title" />
-  <java-symbol type="string" name="throttled_notification_message" />
-  <java-symbol type="string" name="throttled_notification_title" />
-  <java-symbol type="string" name="usb_accessory_notification_title" />
-  <java-symbol type="string" name="usb_cd_installer_notification_title" />
-  <java-symbol type="string" name="usb_mtp_notification_title" />
-  <java-symbol type="string" name="usb_notification_message" />
-  <java-symbol type="string" name="use_physical_keyboard" />
-  <java-symbol type="string" name="usb_ptp_notification_title" />
-  <java-symbol type="string" name="vpn_text" />
-  <java-symbol type="string" name="vpn_text_long" />
-  <java-symbol type="string" name="vpn_title" />
-  <java-symbol type="string" name="vpn_title_long" />
-  <java-symbol type="string" name="vpn_lockdown_connecting" />
-  <java-symbol type="string" name="vpn_lockdown_connected" />
-  <java-symbol type="string" name="vpn_lockdown_error" />
-  <java-symbol type="string" name="vpn_lockdown_reset" />
-  <java-symbol type="string" name="wallpaper_binding_label" />
-  <java-symbol type="style" name="Theme.Dialog.AppError" />
-  <java-symbol type="style" name="Theme.Toast" />
-  <java-symbol type="xml" name="storage_list" />
-  <java-symbol type="bool" name="config_enableDreams" />
-  <java-symbol type="string" name="enable_explore_by_touch_warning_title" />
-  <java-symbol type="string" name="enable_explore_by_touch_warning_message" />
-
-  <java-symbol type="layout" name="resolver_grid" />
-  <java-symbol type="id" name="resolver_grid" />
-  <java-symbol type="id" name="button_once" />
-  <java-symbol type="id" name="button_always" />
-  <java-symbol type="integer" name="config_maxResolverActivityColumns" />
-
-  <!-- From SystemUI -->
-  <java-symbol type="anim" name="push_down_in" />
-  <java-symbol type="anim" name="push_down_out" />
-  <java-symbol type="anim" name="push_up_in" />
-  <java-symbol type="anim" name="push_up_out" />
-  <java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
-  <java-symbol type="dimen" name="status_bar_icon_size" />
-  <java-symbol type="dimen" name="system_bar_icon_size" />
-  <java-symbol type="drawable" name="list_selector_pressed_holo_dark" />
-  <java-symbol type="drawable" name="scrubber_control_disabled_holo" />
-  <java-symbol type="drawable" name="scrubber_control_selector_holo" />
-  <java-symbol type="drawable" name="scrubber_progress_horizontal_holo_dark" />
-  <java-symbol type="drawable" name="usb_android" />
-  <java-symbol type="drawable" name="usb_android_connected" />
-  <java-symbol type="id" name="banner" />
-  <java-symbol type="id" name="mount_button" />
-  <java-symbol type="id" name="unmount_button" />
-  <java-symbol type="layout" name="usb_storage_activity" />
-  <java-symbol type="string" name="chooseUsbActivity" />
-  <java-symbol type="string" name="dlg_confirm_kill_storage_users_text" />
-  <java-symbol type="string" name="dlg_confirm_kill_storage_users_title" />
-  <java-symbol type="string" name="dlg_error_title" />
-  <java-symbol type="string" name="ext_media_badremoval_notification_message" />
-  <java-symbol type="string" name="ext_media_badremoval_notification_title" />
-  <java-symbol type="string" name="ext_media_checking_notification_message" />
-  <java-symbol type="string" name="ext_media_checking_notification_title" />
-  <java-symbol type="string" name="ext_media_nofs_notification_message" />
-  <java-symbol type="string" name="ext_media_nofs_notification_title" />
-  <java-symbol type="string" name="ext_media_nomedia_notification_message" />
-  <java-symbol type="string" name="ext_media_nomedia_notification_title" />
-  <java-symbol type="string" name="ext_media_safe_unmount_notification_message" />
-  <java-symbol type="string" name="ext_media_safe_unmount_notification_title" />
-  <java-symbol type="string" name="ext_media_unmountable_notification_message" />
-  <java-symbol type="string" name="ext_media_unmountable_notification_title" />
-  <java-symbol type="string" name="usb_storage_error_message" />
-  <java-symbol type="string" name="usb_storage_message" />
-  <java-symbol type="string" name="usb_storage_notification_message" />
-  <java-symbol type="string" name="usb_storage_notification_title" />
-  <java-symbol type="string" name="usb_storage_stop_message" />
-  <java-symbol type="string" name="usb_storage_stop_notification_message" />
-  <java-symbol type="string" name="usb_storage_stop_notification_title" />
-  <java-symbol type="string" name="usb_storage_stop_title" />
-  <java-symbol type="string" name="usb_storage_title" />
-  <java-symbol type="style" name="Animation.RecentApplications" />
-
-  <!-- ImfTest -->
-  <java-symbol type="layout" name="auto_complete_list" />
-
-  <!-- From SettingsProvider -->
-  <java-symbol type="raw" name="fallbackring" />
-
-  <!-- From Settings -->
-  <java-symbol type="array" name="config_mobile_hotspot_provision_app" />
-  <java-symbol type="bool" name="config_intrusiveNotificationLed" />
-  <java-symbol type="dimen" name="preference_fragment_padding_bottom" />
-  <java-symbol type="dimen" name="preference_fragment_padding_side" />
-  <java-symbol type="drawable" name="expander_ic_maximized" />
-  <java-symbol type="drawable" name="expander_ic_minimized" />
-  <java-symbol type="drawable" name="ic_menu_archive" />
-  <java-symbol type="drawable" name="ic_menu_goto" />
-  <java-symbol type="drawable" name="ic_settings_language" />
-  <java-symbol type="drawable" name="title_bar_medium" />
-  <java-symbol type="id" name="body" />
-  <java-symbol type="string" name="fast_scroll_alphabet" />
-  <java-symbol type="string" name="ssl_certificate" />
-
-  <!-- From Phone -->
-  <java-symbol type="bool" name="config_built_in_sip_phone" />
-
-  <!-- From TelephonyProvider -->
-  <java-symbol type="xml" name="apns" />
-
-  <!-- From ContactsProvider -->
-  <java-symbol type="array" name="common_nicknames" />
-  <java-symbol type="drawable" name="call_contact" />
-  <java-symbol type="drawable" name="create_contact" />
-  <java-symbol type="string" name="common_name_prefixes" />
-  <java-symbol type="string" name="common_last_name_prefixes" />
-  <java-symbol type="string" name="common_name_suffixes" />
-  <java-symbol type="string" name="common_name_conjunctions" />
-  <java-symbol type="string" name="dial_number_using" />
-  <java-symbol type="string" name="create_contact_using" />
-
-  <!-- From DownloadProvider -->
-  <java-symbol type="integer" name="config_MaxConcurrentDownloadsAllowed" />
-  <java-symbol type="integer" name="config_downloadDataDirSize" />
-  <java-symbol type="integer" name="config_downloadDataDirLowSpaceThreshold" />
-
-  <!-- From Contacts -->
-  <java-symbol type="drawable" name="quickcontact_badge_overlay_dark" />
-
-  <!-- From Browser -->
-  <java-symbol type="drawable" name="ic_menu_moreoverflow_normal_holo_dark" />
-  <java-symbol type="id" name="placeholder" />
-  <java-symbol type="string" name="ssl_certificate_is_valid" />
-
-  <!-- From Mms -->
-  <java-symbol type="drawable" name="ic_menu_play_clip" />
-
-  <!-- From Stk -->
-  <java-symbol type="bool" name="config_sf_slowBlur" />
-  <java-symbol type="drawable" name="ic_volume" />
-  <java-symbol type="drawable" name="stat_notify_sim_toolkit" />
-
-  <!-- From maps library -->
-  <java-symbol type="array" name="maps_starting_lat_lng" />
-  <java-symbol type="array" name="maps_starting_zoom" />
-  <java-symbol type="attr" name="mapViewStyle" />
-  <java-symbol type="attr" name="state_focused" />
-  <java-symbol type="attr" name="state_selected" />
-  <java-symbol type="attr" name="state_pressed" />
-  <java-symbol type="drawable" name="compass_arrow" />
-  <java-symbol type="drawable" name="compass_base" />
-  <java-symbol type="drawable" name="ic_maps_indicator_current_position_anim" />
-  <java-symbol type="drawable" name="loading_tile_android" />
-  <java-symbol type="drawable" name="maps_google_logo" />
-  <java-symbol type="drawable" name="no_tile_256" />
-  <java-symbol type="drawable" name="reticle" />
-
-  <!-- From PinyinIME(!!!) -->
-  <java-symbol type="string" name="inputMethod" />
-
-  <!-- AndroidManifest.xml attributes. -->
-  <eat-comment />
-
 <!-- ===============================================================
      Resources for version 1 of the platform.
      =============================================================== -->
@@ -3782,5 +2013,8 @@
   <public type="attr" name="singleUser" />
   <public type="attr" name="presentationTheme" />
   <public type="attr" name="subtypeId"/>
+  <public type="attr" name="initialKeyguardLayout" />
+  <public type="attr" name="widgetFeatures" />
+  <public type="attr" name="widgetCategory" />
 
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f989e4e..8d4fad7 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -780,6 +780,12 @@
         create and manage their own tokens, bypassing their normal
         Z-ordering. Should never be needed for normal apps.</string>
 
+    <!-- [CHAR LIMIT=NONE] Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_freezeScreen">freeze screen</string>
+    <!-- [CHAR LIMIT=NONE] Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_freezeScreen">Allows the application to temporarily freeze
+        the screen for a full-screen transition.</string>
+    
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_injectEvents">press keys and control buttons</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
new file mode 100644
index 0000000..669ffe7
--- /dev/null
+++ b/core/res/res/values/symbols.xml
@@ -0,0 +1,1789 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* 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.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+
+  <!-- We don't want to publish private symbols in android.R as part of the
+       SDK.  Instead, put them here. -->
+  <private-symbols package="com.android.internal" />
+
+  <!-- Private symbols that we need to reference from framework code.  See
+       frameworks/base/core/res/MakeJavaSymbols.sed for how to easily generate
+       this.
+  -->
+  <java-symbol type="id" name="account_name" />
+  <java-symbol type="id" name="account_row_icon" />
+  <java-symbol type="id" name="account_row_text" />
+  <java-symbol type="id" name="account_type" />
+  <java-symbol type="id" name="action_bar" />
+  <java-symbol type="id" name="action_bar_container" />
+  <java-symbol type="id" name="action_bar_overlay_layout" />
+  <java-symbol type="id" name="action_bar_title" />
+  <java-symbol type="id" name="action_bar_subtitle" />
+  <java-symbol type="id" name="action_context_bar" />
+  <java-symbol type="id" name="action_menu_presenter" />
+  <java-symbol type="id" name="action_mode_close_button" />
+  <java-symbol type="id" name="activity_chooser_view_content" />
+  <java-symbol type="id" name="albumart" />
+  <java-symbol type="id" name="alertTitle" />
+  <java-symbol type="id" name="allow_button" />
+  <java-symbol type="id" name="alwaysUse" />
+  <java-symbol type="id" name="amPm" />
+  <java-symbol type="id" name="authtoken_type" />
+  <java-symbol type="id" name="back_button" />
+  <java-symbol type="id" name="btn_next" />
+  <java-symbol type="id" name="btn_play" />
+  <java-symbol type="id" name="btn_prev" />
+  <java-symbol type="id" name="button_bar" />
+  <java-symbol type="id" name="buttonPanel" />
+  <java-symbol type="id" name="by_common" />
+  <java-symbol type="id" name="by_org" />
+  <java-symbol type="id" name="by_org_unit" />
+  <java-symbol type="id" name="calendar_view" />
+  <java-symbol type="id" name="cancel" />
+  <java-symbol type="id" name="characterPicker" />
+  <java-symbol type="id" name="clearDefaultHint" />
+  <java-symbol type="id" name="contentPanel" />
+  <java-symbol type="id" name="customPanel" />
+  <java-symbol type="id" name="datePicker" />
+  <java-symbol type="id" name="day" />
+  <java-symbol type="id" name="day_names" />
+  <java-symbol type="id" name="decrement" />
+  <java-symbol type="id" name="default_activity_button" />
+  <java-symbol type="id" name="deny_button" />
+  <java-symbol type="id" name="description" />
+  <java-symbol type="id" name="divider" />
+  <java-symbol type="id" name="edit_query" />
+  <java-symbol type="id" name="edittext_container" />
+  <java-symbol type="id" name="enter_pin_section" />
+  <java-symbol type="id" name="expand_activities_button" />
+  <java-symbol type="id" name="expand_button" />
+  <java-symbol type="id" name="expand_button_divider" />
+  <java-symbol type="id" name="expires_on" />
+  <java-symbol type="id" name="find_next" />
+  <java-symbol type="id" name="find_prev" />
+  <java-symbol type="id" name="ffwd" />
+  <java-symbol type="id" name="fillInIntent" />
+  <java-symbol type="id" name="find" />
+  <java-symbol type="id" name="fullscreenArea" />
+  <java-symbol type="id" name="hard_keyboard_section" />
+  <java-symbol type="id" name="hard_keyboard_switch" />
+  <java-symbol type="id" name="headers" />
+  <java-symbol type="id" name="hour" />
+  <java-symbol type="id" name="icon" />
+  <java-symbol type="id" name="image" />
+  <java-symbol type="id" name="increment" />
+  <java-symbol type="id" name="internalEmpty" />
+  <java-symbol type="id" name="info" />
+  <java-symbol type="id" name="inputExtractAccessories" />
+  <java-symbol type="id" name="inputExtractAction" />
+  <java-symbol type="id" name="inputExtractEditButton" />
+  <java-symbol type="id" name="issued_on" />
+  <java-symbol type="id" name="left_icon" />
+  <java-symbol type="id" name="leftSpacer" />
+  <java-symbol type="id" name="line1" />
+  <java-symbol type="id" name="line3" />
+  <java-symbol type="id" name="list_footer" />
+  <java-symbol type="id" name="list_item" />
+  <java-symbol type="id" name="listContainer" />
+  <java-symbol type="id" name="locale" />
+  <java-symbol type="id" name="matches" />
+  <java-symbol type="id" name="mediacontroller_progress" />
+  <java-symbol type="id" name="minute" />
+  <java-symbol type="id" name="mode_normal" />
+  <java-symbol type="id" name="month" />
+  <java-symbol type="id" name="month_name" />
+  <java-symbol type="id" name="name" />
+  <java-symbol type="id" name="next" />
+  <java-symbol type="id" name="next_button" />
+  <java-symbol type="id" name="new_app_action" />
+  <java-symbol type="id" name="new_app_description" />
+  <java-symbol type="id" name="new_app_icon" />
+  <java-symbol type="id" name="no_permissions" />
+  <java-symbol type="id" name="numberpicker_input" />
+  <java-symbol type="id" name="old_app_action" />
+  <java-symbol type="id" name="old_app_description" />
+  <java-symbol type="id" name="old_app_icon" />
+  <java-symbol type="id" name="overlay_display_window_texture" />
+  <java-symbol type="id" name="overlay_display_window_title" />
+  <java-symbol type="id" name="package_label" />
+  <java-symbol type="id" name="packages_list" />
+  <java-symbol type="id" name="pause" />
+  <java-symbol type="id" name="show_more" />
+  <java-symbol type="id" name="perm_icon" />
+  <java-symbol type="id" name="show_more_icon" />
+  <java-symbol type="id" name="show_more_text" />
+  <java-symbol type="id" name="dangerous_perms_list" />
+  <java-symbol type="id" name="non_dangerous_perms_list" />
+  <java-symbol type="id" name="permission_group" />
+  <java-symbol type="id" name="permission_list" />
+  <java-symbol type="id" name="pickers" />
+  <java-symbol type="id" name="prefs" />
+  <java-symbol type="id" name="prefs_frame" />
+  <java-symbol type="id" name="prev" />
+  <java-symbol type="id" name="progress" />
+  <java-symbol type="id" name="progress_circular" />
+  <java-symbol type="id" name="progress_horizontal" />
+  <java-symbol type="id" name="progress_number" />
+  <java-symbol type="id" name="progress_percent" />
+  <java-symbol type="id" name="progressContainer" />
+  <java-symbol type="id" name="rew" />
+  <java-symbol type="id" name="rightSpacer" />
+  <java-symbol type="id" name="rowTypeId" />
+  <java-symbol type="id" name="scrollView" />
+  <java-symbol type="id" name="search_app_icon" />
+  <java-symbol type="id" name="search_badge" />
+  <java-symbol type="id" name="search_bar" />
+  <java-symbol type="id" name="search_button" />
+  <java-symbol type="id" name="search_close_btn" />
+  <java-symbol type="id" name="search_edit_frame" />
+  <java-symbol type="id" name="search_go_btn" />
+  <java-symbol type="id" name="search_mag_icon" />
+  <java-symbol type="id" name="search_plate" />
+  <java-symbol type="id" name="search_src_text" />
+  <java-symbol type="id" name="search_view" />
+  <java-symbol type="id" name="search_voice_btn" />
+  <java-symbol type="id" name="select_all" />
+  <java-symbol type="id" name="serial_number" />
+  <java-symbol type="id" name="seekbar" />
+  <java-symbol type="id" name="sha1_fingerprint" />
+  <java-symbol type="id" name="sha256_fingerprint" />
+  <java-symbol type="id" name="share" />
+  <java-symbol type="id" name="shortcut" />
+  <java-symbol type="id" name="skip_button" />
+  <java-symbol type="id" name="slider_group" />
+  <java-symbol type="id" name="split_action_bar" />
+  <java-symbol type="id" name="stream_icon" />
+  <java-symbol type="id" name="submit_area" />
+  <java-symbol type="id" name="switch_new" />
+  <java-symbol type="id" name="switch_old" />
+  <java-symbol type="id" name="switchWidget" />
+  <java-symbol type="id" name="text" />
+  <java-symbol type="id" name="time" />
+  <java-symbol type="id" name="time_current" />
+  <java-symbol type="id" name="timeDisplayBackground" />
+  <java-symbol type="id" name="timeDisplayForeground" />
+  <java-symbol type="id" name="titleDivider" />
+  <java-symbol type="id" name="titleDividerTop" />
+  <java-symbol type="id" name="timePicker" />
+  <java-symbol type="id" name="title_template" />
+  <java-symbol type="id" name="to_common" />
+  <java-symbol type="id" name="to_org" />
+  <java-symbol type="id" name="to_org_unit" />
+  <java-symbol type="id" name="top_action_bar" />
+  <java-symbol type="id" name="topPanel" />
+  <java-symbol type="id" name="up" />
+  <java-symbol type="id" name="value" />
+  <java-symbol type="id" name="visible_panel" />
+  <java-symbol type="id" name="websearch" />
+  <java-symbol type="id" name="wifi_p2p_wps_pin" />
+  <java-symbol type="id" name="year" />
+  <java-symbol type="id" name="zoomControls" />
+  <java-symbol type="id" name="zoomIn" />
+  <java-symbol type="id" name="zoomMagnify" />
+  <java-symbol type="id" name="zoomOut" />
+  <java-symbol type="id" name="actions" />
+  <java-symbol type="id" name="action0" />
+  <java-symbol type="id" name="action1" />
+  <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="id" name="inbox_text0" />
+  <java-symbol type="id" name="inbox_text1" />
+  <java-symbol type="id" name="inbox_text2" />
+  <java-symbol type="id" name="inbox_text3" />
+  <java-symbol type="id" name="inbox_text4" />
+  <java-symbol type="id" name="inbox_text5" />
+  <java-symbol type="id" name="inbox_text6" />
+  <java-symbol type="id" name="inbox_more" />
+  <java-symbol type="id" name="status_bar_latest_event_content" />
+  <java-symbol type="id" name="action_divider" />
+  <java-symbol type="id" name="overflow_divider" />
+
+  <java-symbol type="attr" name="actionModeShareDrawable" />
+  <java-symbol type="attr" name="alertDialogCenterButtons" />
+  <java-symbol type="attr" name="gestureOverlayViewStyle" />
+  <java-symbol type="attr" name="keyboardViewStyle" />
+  <java-symbol type="attr" name="numberPickerStyle" />
+  <java-symbol type="attr" name="pointerStyle" />
+  <java-symbol type="attr" name="preferenceFrameLayoutStyle" />
+  <java-symbol type="attr" name="searchDialogTheme" />
+  <java-symbol type="attr" name="searchViewSearchIcon" />
+  <java-symbol type="attr" name="stackViewStyle" />
+  <java-symbol type="attr" name="switchStyle" />
+  <java-symbol type="attr" name="textAppearanceAutoCorrectionSuggestion" />
+  <java-symbol type="attr" name="textAppearanceEasyCorrectSuggestion" />
+  <java-symbol type="attr" name="textAppearanceMisspelledSuggestion" />
+  <java-symbol type="attr" name="textColorSearchUrl" />
+  <java-symbol type="attr" name="timePickerStyle" />
+  <java-symbol type="attr" name="windowFixedWidthMajor" />
+  <java-symbol type="attr" name="windowFixedWidthMinor" />
+  <java-symbol type="attr" name="windowFixedHeightMajor" />
+  <java-symbol type="attr" name="windowFixedHeightMinor" />
+  <java-symbol type="attr" name="accessibilityFocusedDrawable"/>
+
+  <java-symbol type="bool" name="action_bar_embed_tabs" />
+  <java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" />
+  <java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" />
+  <java-symbol type="bool" name="config_allowActionMenuItemTextWithIcon" />
+  <java-symbol type="bool" name="config_bluetooth_adapter_quick_switch" />
+  <java-symbol type="bool" name="config_bluetooth_sco_off_call" />
+  <java-symbol type="bool" name="config_cellBroadcastAppLinks" />
+  <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
+  <java-symbol type="bool" name="config_enable_emergency_call_while_sim_locked" />
+  <java-symbol type="bool" name="config_enable_puk_unlock_screen" />
+  <java-symbol type="bool" name="config_mms_content_disposition_support" />
+  <java-symbol type="bool" name="config_showMenuShortcutsWhenKeyboardPresent" />
+  <java-symbol type="bool" name="config_sip_wifi_only" />
+  <java-symbol type="bool" name="config_sms_capable" />
+  <java-symbol type="bool" name="config_sms_utf8_support" />
+  <java-symbol type="bool" name="config_swipeDisambiguation" />
+  <java-symbol type="bool" name="config_syncstorageengine_masterSyncAutomatically" />
+  <java-symbol type="bool" name="config_telephony_use_own_number_for_voicemail" />
+  <java-symbol type="bool" name="config_ui_enableFadingMarquee" />
+  <java-symbol type="bool" name="config_use_strict_phone_number_comparation" />
+  <java-symbol type="bool" name="config_voice_capable" />
+  <java-symbol type="bool" name="preferences_prefer_dual_pane" />
+  <java-symbol type="bool" name="skip_restoring_network_selection" />
+  <java-symbol type="bool" name="split_action_bar_is_narrow" />
+  <java-symbol type="bool" name="config_useMasterVolume" />
+  <java-symbol type="bool" name="config_useVolumeKeySounds" />
+  <java-symbol type="bool" name="config_enableWallpaperService" />
+  <java-symbol type="bool" name="config_sendAudioBecomingNoisy" />
+  <java-symbol type="bool" name="config_enableScreenshotChord" />
+  <java-symbol type="bool" name="config_bluetooth_default_profiles" />
+
+  <java-symbol type="integer" name="config_cursorWindowSize" />
+  <java-symbol type="integer" name="config_longPressOnPowerBehavior" />
+  <java-symbol type="integer" name="config_max_pan_devices" />
+  <java-symbol type="integer" name="config_ntpTimeout" />
+  <java-symbol type="integer" name="config_wifi_framework_scan_interval" />
+  <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
+  <java-symbol type="integer" name="db_connection_pool_size" />
+  <java-symbol type="integer" name="db_journal_size_limit" />
+  <java-symbol type="integer" name="db_wal_autocheckpoint" />
+  <java-symbol type="integer" name="max_action_buttons" />
+  <java-symbol type="integer" name="config_wifi_driver_stop_delay" />
+  <java-symbol type="integer" name="config_soundEffectVolumeDb" />
+  <java-symbol type="integer" name="config_lockSoundVolumeDb" />
+  <java-symbol type="integer" name="config_multiuserMaximumUsers" />
+
+  <java-symbol type="color" name="tab_indicator_text_v4" />
+
+  <java-symbol type="dimen" name="config_prefDialogWidth" />
+  <java-symbol type="dimen" name="config_viewConfigurationTouchSlop" />
+  <java-symbol type="dimen" name="default_app_widget_padding_bottom" />
+  <java-symbol type="dimen" name="default_app_widget_padding_left" />
+  <java-symbol type="dimen" name="default_app_widget_padding_right" />
+  <java-symbol type="dimen" name="default_app_widget_padding_top" />
+  <java-symbol type="dimen" name="default_gap" />
+  <java-symbol type="dimen" name="dropdownitem_icon_width" />
+  <java-symbol type="dimen" name="dropdownitem_text_padding_left" />
+  <java-symbol type="dimen" name="fastscroll_overlay_size" />
+  <java-symbol type="dimen" name="fastscroll_thumb_height" />
+  <java-symbol type="dimen" name="fastscroll_thumb_width" />
+  <java-symbol type="dimen" name="fastscroll_thumb_width" />
+  <java-symbol type="dimen" name="password_keyboard_spacebar_vertical_correction" />
+  <java-symbol type="dimen" name="search_view_preferred_width" />
+  <java-symbol type="dimen" name="textview_error_popup_default_width" />
+  <java-symbol type="dimen" name="toast_y_offset" />
+  <java-symbol type="dimen" name="volume_panel_top" />
+  <java-symbol type="dimen" name="action_bar_stacked_max_height" />
+  <java-symbol type="dimen" name="action_bar_stacked_tab_max_width" />
+  <java-symbol type="dimen" name="notification_text_size" />
+  <java-symbol type="dimen" name="notification_title_text_size" />
+  <java-symbol type="dimen" name="notification_subtext_size" />
+
+  <java-symbol type="string" name="add_account_button_label" />
+  <java-symbol type="string" name="addToDictionary" />
+  <java-symbol type="string" name="action_bar_home_description" />
+  <java-symbol type="string" name="action_bar_up_description" />
+  <java-symbol type="string" name="delete" />
+  <java-symbol type="string" name="deleteText" />
+  <java-symbol type="string" name="ellipsis_two_dots" />
+  <java-symbol type="string" name="ellipsis" />
+  <java-symbol type="string" name="grant_permissions_header_text" />
+  <java-symbol type="string" name="list_delimeter" />
+  <java-symbol type="string" name="menu_delete_shortcut_label" />
+  <java-symbol type="string" name="menu_enter_shortcut_label" />
+  <java-symbol type="string" name="menu_space_shortcut_label" />
+  <java-symbol type="string" name="notification_title" />
+  <java-symbol type="string" name="permission_request_notification_with_subtitle" />
+  <java-symbol type="string" name="prepend_shortcut_label" />
+  <java-symbol type="string" name="replace" />
+  <java-symbol type="string" name="textSelectionCABTitle" />
+  <java-symbol type="string" name="BaMmi" />
+  <java-symbol type="string" name="CLIRDefaultOffNextCallOff" />
+  <java-symbol type="string" name="CLIRDefaultOffNextCallOn" />
+  <java-symbol type="string" name="CLIRDefaultOnNextCallOff" />
+  <java-symbol type="string" name="CLIRDefaultOnNextCallOn" />
+  <java-symbol type="string" name="CLIRPermanent" />
+  <java-symbol type="string" name="CfMmi" />
+  <java-symbol type="string" name="ClipMmi" />
+  <java-symbol type="string" name="ClirMmi" />
+  <java-symbol type="string" name="CwMmi" />
+  <java-symbol type="string" name="Midnight" />
+  <java-symbol type="string" name="Noon" />
+  <java-symbol type="string" name="PinMmi" />
+  <java-symbol type="string" name="PwdMmi" />
+  <java-symbol type="string" name="RestrictedChangedTitle" />
+  <java-symbol type="string" name="RestrictedOnAllVoice" />
+  <java-symbol type="string" name="RestrictedOnData" />
+  <java-symbol type="string" name="RestrictedOnEmergency" />
+  <java-symbol type="string" name="RestrictedOnNormal" />
+  <java-symbol type="string" name="SetupCallDefault" />
+  <java-symbol type="string" name="abbrev_month" />
+  <java-symbol type="string" name="abbrev_month_day" />
+  <java-symbol type="string" name="abbrev_month_day_year" />
+  <java-symbol type="string" name="abbrev_month_year" />
+  <java-symbol type="string" name="accept" />
+  <java-symbol type="string" name="activity_chooser_view_see_all" />
+  <java-symbol type="string" name="activitychooserview_choose_application" />
+  <java-symbol type="string" name="alternate_eri_file" />
+  <java-symbol type="string" name="alwaysUse" />
+  <java-symbol type="string" name="am" />
+  <java-symbol type="string" name="autofill_address_line_1_label_re" />
+  <java-symbol type="string" name="autofill_address_line_1_re" />
+  <java-symbol type="string" name="autofill_address_line_2_re" />
+  <java-symbol type="string" name="autofill_address_line_3_re" />
+  <java-symbol type="string" name="autofill_address_name_separator" />
+  <java-symbol type="string" name="autofill_address_summary_format" />
+  <java-symbol type="string" name="autofill_address_summary_name_format" />
+  <java-symbol type="string" name="autofill_address_summary_separator" />
+  <java-symbol type="string" name="autofill_address_type_same_as_re" />
+  <java-symbol type="string" name="autofill_address_type_use_my_re" />
+  <java-symbol type="string" name="autofill_area" />
+  <java-symbol type="string" name="autofill_area_code_notext_re" />
+  <java-symbol type="string" name="autofill_area_code_re" />
+  <java-symbol type="string" name="autofill_attention_ignored_re" />
+  <java-symbol type="string" name="autofill_billing_designator_re" />
+  <java-symbol type="string" name="autofill_card_cvc_re" />
+  <java-symbol type="string" name="autofill_card_ignored_re" />
+  <java-symbol type="string" name="autofill_card_number_re" />
+  <java-symbol type="string" name="autofill_city_re" />
+  <java-symbol type="string" name="autofill_company_re" />
+  <java-symbol type="string" name="autofill_country_code_re" />
+  <java-symbol type="string" name="autofill_country_re" />
+  <java-symbol type="string" name="autofill_county" />
+  <java-symbol type="string" name="autofill_department" />
+  <java-symbol type="string" name="autofill_district" />
+  <java-symbol type="string" name="autofill_email_re" />
+  <java-symbol type="string" name="autofill_emirate" />
+  <java-symbol type="string" name="autofill_expiration_date_re" />
+  <java-symbol type="string" name="autofill_expiration_month_re" />
+  <java-symbol type="string" name="autofill_fax_re" />
+  <java-symbol type="string" name="autofill_first_name_re" />
+  <java-symbol type="string" name="autofill_island" />
+  <java-symbol type="string" name="autofill_last_name_re" />
+  <java-symbol type="string" name="autofill_middle_initial_re" />
+  <java-symbol type="string" name="autofill_middle_name_re" />
+  <java-symbol type="string" name="autofill_name_on_card_contextual_re" />
+  <java-symbol type="string" name="autofill_name_on_card_re" />
+  <java-symbol type="string" name="autofill_name_re" />
+  <java-symbol type="string" name="autofill_name_specific_re" />
+  <java-symbol type="string" name="autofill_parish" />
+  <java-symbol type="string" name="autofill_phone_extension_re" />
+  <java-symbol type="string" name="autofill_phone_prefix_re" />
+  <java-symbol type="string" name="autofill_phone_prefix_separator_re" />
+  <java-symbol type="string" name="autofill_phone_re" />
+  <java-symbol type="string" name="autofill_phone_suffix_re" />
+  <java-symbol type="string" name="autofill_phone_suffix_separator_re" />
+  <java-symbol type="string" name="autofill_postal_code" />
+  <java-symbol type="string" name="autofill_prefecture" />
+  <java-symbol type="string" name="autofill_province" />
+  <java-symbol type="string" name="autofill_region_ignored_re" />
+  <java-symbol type="string" name="autofill_shipping_designator_re" />
+  <java-symbol type="string" name="autofill_state" />
+  <java-symbol type="string" name="autofill_state_re" />
+  <java-symbol type="string" name="autofill_this_form" />
+  <java-symbol type="string" name="autofill_username_re" />
+  <java-symbol type="string" name="autofill_zip_4_re" />
+  <java-symbol type="string" name="autofill_zip_code" />
+  <java-symbol type="string" name="autofill_zip_code_re" />
+  <java-symbol type="string" name="badPin" />
+  <java-symbol type="string" name="badPuk" />
+  <java-symbol type="string" name="byteShort" />
+  <java-symbol type="string" name="cfTemplateForwarded" />
+  <java-symbol type="string" name="cfTemplateForwardedTime" />
+  <java-symbol type="string" name="cfTemplateNotForwarded" />
+  <java-symbol type="string" name="cfTemplateRegistered" />
+  <java-symbol type="string" name="cfTemplateRegisteredTime" />
+  <java-symbol type="string" name="chooseActivity" />
+  <java-symbol type="string" name="config_default_dns_server" />
+  <java-symbol type="string" name="config_ethernet_iface_regex" />
+  <java-symbol type="string" name="config_ntpServer" />
+  <java-symbol type="string" name="config_tether_apndata" />
+  <java-symbol type="string" name="config_useragentprofile_url" />
+  <java-symbol type="string" name="config_wifi_p2p_device_type" />
+  <java-symbol type="string" name="contentServiceSync" />
+  <java-symbol type="string" name="contentServiceSyncNotificationTitle" />
+  <java-symbol type="string" name="contentServiceTooManyDeletesNotificationDesc" />
+  <java-symbol type="string" name="date1_date2" />
+  <java-symbol type="string" name="date1_time1_date2_time2" />
+  <java-symbol type="string" name="date_and_time" />
+  <java-symbol type="string" name="date_picker_decrement_day_button" />
+  <java-symbol type="string" name="date_picker_decrement_month_button" />
+  <java-symbol type="string" name="date_picker_decrement_year_button" />
+  <java-symbol type="string" name="date_picker_dialog_title" />
+  <java-symbol type="string" name="date_picker_increment_day_button" />
+  <java-symbol type="string" name="date_picker_increment_month_button" />
+  <java-symbol type="string" name="date_picker_increment_year_button" />
+  <java-symbol type="string" name="date_time" />
+  <java-symbol type="string" name="date_time_set" />
+  <java-symbol type="string" name="date_time_done" />
+  <java-symbol type="string" name="day_of_week_long_friday" />
+  <java-symbol type="string" name="day_of_week_long_monday" />
+  <java-symbol type="string" name="day_of_week_long_saturday" />
+  <java-symbol type="string" name="day_of_week_long_sunday" />
+  <java-symbol type="string" name="day_of_week_long_thursday" />
+  <java-symbol type="string" name="day_of_week_long_tuesday" />
+  <java-symbol type="string" name="day_of_week_long_wednesday" />
+  <java-symbol type="string" name="day_of_week_medium_friday" />
+  <java-symbol type="string" name="day_of_week_medium_monday" />
+  <java-symbol type="string" name="day_of_week_medium_saturday" />
+  <java-symbol type="string" name="day_of_week_medium_sunday" />
+  <java-symbol type="string" name="day_of_week_medium_thursday" />
+  <java-symbol type="string" name="day_of_week_medium_tuesday" />
+  <java-symbol type="string" name="day_of_week_medium_wednesday" />
+  <java-symbol type="string" name="day_of_week_short_friday" />
+  <java-symbol type="string" name="day_of_week_short_monday" />
+  <java-symbol type="string" name="day_of_week_short_saturday" />
+  <java-symbol type="string" name="day_of_week_short_sunday" />
+  <java-symbol type="string" name="day_of_week_short_thursday" />
+  <java-symbol type="string" name="day_of_week_short_tuesday" />
+  <java-symbol type="string" name="day_of_week_short_wednesday" />
+  <java-symbol type="string" name="day_of_week_shortest_friday" />
+  <java-symbol type="string" name="day_of_week_shortest_monday" />
+  <java-symbol type="string" name="day_of_week_shortest_saturday" />
+  <java-symbol type="string" name="day_of_week_shortest_sunday" />
+  <java-symbol type="string" name="day_of_week_shortest_thursday" />
+  <java-symbol type="string" name="day_of_week_shortest_tuesday" />
+  <java-symbol type="string" name="day_of_week_shortest_wednesday" />
+  <java-symbol type="string" name="db_default_journal_mode" />
+  <java-symbol type="string" name="db_default_sync_mode" />
+  <java-symbol type="string" name="db_wal_sync_mode" />
+  <java-symbol type="string" name="decline" />
+  <java-symbol type="string" name="default_text_encoding" />
+  <java-symbol type="string" name="description_target_unlock_tablet" />
+  <java-symbol type="string" name="display_manager_built_in_display_name" />
+  <java-symbol type="string" name="display_manager_hdmi_display_name" />
+  <java-symbol type="string" name="display_manager_overlay_display_name" />
+  <java-symbol type="string" name="display_manager_overlay_display_title" />
+  <java-symbol type="string" name="double_tap_toast" />
+  <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" />
+  <java-symbol type="string" name="elapsed_time_short_format_mm_ss" />
+  <java-symbol type="string" name="emailTypeCustom" />
+  <java-symbol type="string" name="emailTypeHome" />
+  <java-symbol type="string" name="emailTypeMobile" />
+  <java-symbol type="string" name="emailTypeOther" />
+  <java-symbol type="string" name="emailTypeWork" />
+  <java-symbol type="string" name="emergency_call_dialog_number_for_display" />
+  <java-symbol type="string" name="emergency_calls_only" />
+  <java-symbol type="string" name="eventTypeAnniversary" />
+  <java-symbol type="string" name="eventTypeBirthday" />
+  <java-symbol type="string" name="eventTypeCustom" />
+  <java-symbol type="string" name="eventTypeOther" />
+  <java-symbol type="string" name="extmedia_format_button_format" />
+  <java-symbol type="string" name="extmedia_format_message" />
+  <java-symbol type="string" name="extmedia_format_title" />
+  <java-symbol type="string" name="fileSizeSuffix" />
+  <java-symbol type="string" name="force_close" />
+  <java-symbol type="string" name="format_error" />
+  <java-symbol type="string" name="gadget_host_error_inflating" />
+  <java-symbol type="string" name="gigabyteShort" />
+  <java-symbol type="string" name="gpsNotifMessage" />
+  <java-symbol type="string" name="gpsNotifTicker" />
+  <java-symbol type="string" name="gpsNotifTitle" />
+  <java-symbol type="string" name="gpsVerifNo" />
+  <java-symbol type="string" name="gpsVerifYes" />
+  <java-symbol type="string" name="gsm_alphabet_default_charset" />
+  <java-symbol type="string" name="hour_ampm" />
+  <java-symbol type="string" name="hour_cap_ampm" />
+  <java-symbol type="string" name="hour_minute_24" />
+  <java-symbol type="string" name="hour_minute_ampm" />
+  <java-symbol type="string" name="hour_minute_cap_ampm" />
+  <java-symbol type="string" name="httpError" />
+  <java-symbol type="string" name="httpErrorAuth" />
+  <java-symbol type="string" name="httpErrorConnect" />
+  <java-symbol type="string" name="httpErrorFailedSslHandshake" />
+  <java-symbol type="string" name="httpErrorFile" />
+  <java-symbol type="string" name="httpErrorFileNotFound" />
+  <java-symbol type="string" name="httpErrorIO" />
+  <java-symbol type="string" name="httpErrorLookup" />
+  <java-symbol type="string" name="httpErrorOk" />
+  <java-symbol type="string" name="httpErrorProxyAuth" />
+  <java-symbol type="string" name="httpErrorRedirectLoop" />
+  <java-symbol type="string" name="httpErrorTimeout" />
+  <java-symbol type="string" name="httpErrorTooManyRequests" />
+  <java-symbol type="string" name="httpErrorUnsupportedAuthScheme" />
+  <java-symbol type="string" name="imProtocolAim" />
+  <java-symbol type="string" name="imProtocolCustom" />
+  <java-symbol type="string" name="imProtocolGoogleTalk" />
+  <java-symbol type="string" name="imProtocolIcq" />
+  <java-symbol type="string" name="imProtocolJabber" />
+  <java-symbol type="string" name="imProtocolMsn" />
+  <java-symbol type="string" name="imProtocolNetMeeting" />
+  <java-symbol type="string" name="imProtocolQq" />
+  <java-symbol type="string" name="imProtocolSkype" />
+  <java-symbol type="string" name="imProtocolYahoo" />
+  <java-symbol type="string" name="imTypeCustom" />
+  <java-symbol type="string" name="imTypeHome" />
+  <java-symbol type="string" name="imTypeOther" />
+  <java-symbol type="string" name="imTypeWork" />
+  <java-symbol type="string" name="ime_action_default" />
+  <java-symbol type="string" name="ime_action_done" />
+  <java-symbol type="string" name="ime_action_go" />
+  <java-symbol type="string" name="ime_action_next" />
+  <java-symbol type="string" name="ime_action_previous" />
+  <java-symbol type="string" name="ime_action_search" />
+  <java-symbol type="string" name="ime_action_send" />
+  <java-symbol type="string" name="invalidPin" />
+  <java-symbol type="string" name="js_dialog_before_unload" />
+  <java-symbol type="string" name="js_dialog_title" />
+  <java-symbol type="string" name="js_dialog_title_default" />
+  <java-symbol type="string" name="keyboard_headset_required_to_hear_password" />
+  <java-symbol type="string" name="keyboard_password_character_no_headset" />
+  <java-symbol type="string" name="keyboardview_keycode_alt" />
+  <java-symbol type="string" name="keyboardview_keycode_cancel" />
+  <java-symbol type="string" name="keyboardview_keycode_delete" />
+  <java-symbol type="string" name="keyboardview_keycode_done" />
+  <java-symbol type="string" name="keyboardview_keycode_enter" />
+  <java-symbol type="string" name="keyboardview_keycode_mode_change" />
+  <java-symbol type="string" name="keyboardview_keycode_shift" />
+  <java-symbol type="string" name="kilobyteShort" />
+  <java-symbol type="string" name="last_month" />
+  <java-symbol type="string" name="launchBrowserDefault" />
+  <java-symbol type="string" name="lockscreen_access_pattern_cell_added" />
+  <java-symbol type="string" name="lockscreen_access_pattern_cleared" />
+  <java-symbol type="string" name="lockscreen_access_pattern_detected" />
+  <java-symbol type="string" name="lockscreen_access_pattern_start" />
+  <java-symbol type="string" name="lockscreen_emergency_call" />
+  <java-symbol type="string" name="lockscreen_return_to_call" />
+  <java-symbol type="string" name="lockscreen_transport_pause_description" />
+  <java-symbol type="string" name="lockscreen_transport_play_description" />
+  <java-symbol type="string" name="lockscreen_transport_stop_description" />
+  <java-symbol type="string" name="low_memory" />
+  <java-symbol type="string" name="media_bad_removal" />
+  <java-symbol type="string" name="media_checking" />
+  <java-symbol type="string" name="media_removed" />
+  <java-symbol type="string" name="media_shared" />
+  <java-symbol type="string" name="media_unknown_state" />
+  <java-symbol type="string" name="megabyteShort" />
+  <java-symbol type="string" name="midnight" />
+  <java-symbol type="string" name="mismatchPin" />
+  <java-symbol type="string" name="mmiComplete" />
+  <java-symbol type="string" name="mmiError" />
+  <java-symbol type="string" name="mmiFdnError" />
+  <java-symbol type="string" name="month" />
+  <java-symbol type="string" name="month_day" />
+  <java-symbol type="string" name="month_day_year" />
+  <java-symbol type="string" name="month_long_april" />
+  <java-symbol type="string" name="month_long_august" />
+  <java-symbol type="string" name="month_long_december" />
+  <java-symbol type="string" name="month_long_february" />
+  <java-symbol type="string" name="month_long_january" />
+  <java-symbol type="string" name="month_long_july" />
+  <java-symbol type="string" name="month_long_june" />
+  <java-symbol type="string" name="month_long_march" />
+  <java-symbol type="string" name="month_long_may" />
+  <java-symbol type="string" name="month_long_november" />
+  <java-symbol type="string" name="month_long_october" />
+  <java-symbol type="string" name="month_long_september" />
+  <java-symbol type="string" name="month_long_standalone_april" />
+  <java-symbol type="string" name="month_long_standalone_august" />
+  <java-symbol type="string" name="month_long_standalone_december" />
+  <java-symbol type="string" name="month_long_standalone_february" />
+  <java-symbol type="string" name="month_long_standalone_january" />
+  <java-symbol type="string" name="month_long_standalone_july" />
+  <java-symbol type="string" name="month_long_standalone_june" />
+  <java-symbol type="string" name="month_long_standalone_march" />
+  <java-symbol type="string" name="month_long_standalone_may" />
+  <java-symbol type="string" name="month_long_standalone_november" />
+  <java-symbol type="string" name="month_long_standalone_october" />
+  <java-symbol type="string" name="month_long_standalone_september" />
+  <java-symbol type="string" name="month_medium_april" />
+  <java-symbol type="string" name="month_medium_august" />
+  <java-symbol type="string" name="month_medium_december" />
+  <java-symbol type="string" name="month_medium_february" />
+  <java-symbol type="string" name="month_medium_january" />
+  <java-symbol type="string" name="month_medium_july" />
+  <java-symbol type="string" name="month_medium_june" />
+  <java-symbol type="string" name="month_medium_march" />
+  <java-symbol type="string" name="month_medium_may" />
+  <java-symbol type="string" name="month_medium_november" />
+  <java-symbol type="string" name="month_medium_october" />
+  <java-symbol type="string" name="month_medium_september" />
+  <java-symbol type="string" name="month_shortest_april" />
+  <java-symbol type="string" name="month_shortest_august" />
+  <java-symbol type="string" name="month_shortest_december" />
+  <java-symbol type="string" name="month_shortest_february" />
+  <java-symbol type="string" name="month_shortest_january" />
+  <java-symbol type="string" name="month_shortest_july" />
+  <java-symbol type="string" name="month_shortest_june" />
+  <java-symbol type="string" name="month_shortest_march" />
+  <java-symbol type="string" name="month_shortest_may" />
+  <java-symbol type="string" name="month_shortest_november" />
+  <java-symbol type="string" name="month_shortest_october" />
+  <java-symbol type="string" name="month_shortest_september" />
+  <java-symbol type="string" name="month_year" />
+  <java-symbol type="string" name="more_item_label" />
+  <java-symbol type="string" name="needPuk" />
+  <java-symbol type="string" name="needPuk2" />
+  <java-symbol type="string" name="new_app_action" />
+  <java-symbol type="string" name="new_app_description" />
+  <java-symbol type="string" name="noApplications" />
+  <java-symbol type="string" name="no_file_chosen" />
+  <java-symbol type="string" name="no_matches" />
+  <java-symbol type="string" name="noon" />
+  <java-symbol type="string" name="number_picker_increment_scroll_action" />
+  <java-symbol type="string" name="number_picker_increment_scroll_mode" />
+  <java-symbol type="string" name="numeric_date" />
+  <java-symbol type="string" name="numeric_date_format" />
+  <java-symbol type="string" name="numeric_date_template" />
+  <java-symbol type="string" name="numeric_md1_md2" />
+  <java-symbol type="string" name="numeric_md1_time1_md2_time2" />
+  <java-symbol type="string" name="numeric_mdy1_mdy2" />
+  <java-symbol type="string" name="numeric_mdy1_time1_mdy2_time2" />
+  <java-symbol type="string" name="numeric_wday1_md1_time1_wday2_md2_time2" />
+  <java-symbol type="string" name="numeric_wday1_md1_wday2_md2" />
+  <java-symbol type="string" name="numeric_wday1_mdy1_time1_wday2_mdy2_time2" />
+  <java-symbol type="string" name="numeric_wday1_mdy1_wday2_mdy2" />
+  <java-symbol type="string" name="old_app_action" />
+  <java-symbol type="string" name="old_app_description" />
+  <java-symbol type="string" name="older" />
+  <java-symbol type="string" name="open_permission_deny" />
+  <java-symbol type="string" name="orgTypeCustom" />
+  <java-symbol type="string" name="orgTypeOther" />
+  <java-symbol type="string" name="orgTypeWork" />
+  <java-symbol type="string" name="passwordIncorrect" />
+  <java-symbol type="string" name="perms_description_app" />
+  <java-symbol type="string" name="perms_new_perm_prefix" />
+  <java-symbol type="string" name="perms_hide" />
+  <java-symbol type="string" name="perms_show_all" />
+  <java-symbol type="string" name="default_permission_group" />
+  <java-symbol type="string" name="permissions_format" />
+  <java-symbol type="string" name="petabyteShort" />
+  <java-symbol type="string" name="phoneTypeAssistant" />
+  <java-symbol type="string" name="phoneTypeCallback" />
+  <java-symbol type="string" name="phoneTypeCar" />
+  <java-symbol type="string" name="phoneTypeCompanyMain" />
+  <java-symbol type="string" name="phoneTypeCustom" />
+  <java-symbol type="string" name="phoneTypeFaxHome" />
+  <java-symbol type="string" name="phoneTypeFaxWork" />
+  <java-symbol type="string" name="phoneTypeHome" />
+  <java-symbol type="string" name="phoneTypeIsdn" />
+  <java-symbol type="string" name="phoneTypeMain" />
+  <java-symbol type="string" name="phoneTypeMms" />
+  <java-symbol type="string" name="phoneTypeMobile" />
+  <java-symbol type="string" name="phoneTypeOther" />
+  <java-symbol type="string" name="phoneTypeOtherFax" />
+  <java-symbol type="string" name="phoneTypePager" />
+  <java-symbol type="string" name="phoneTypeRadio" />
+  <java-symbol type="string" name="phoneTypeTelex" />
+  <java-symbol type="string" name="phoneTypeTtyTdd" />
+  <java-symbol type="string" name="phoneTypeWork" />
+  <java-symbol type="string" name="phoneTypeWorkMobile" />
+  <java-symbol type="string" name="phoneTypeWorkPager" />
+  <java-symbol type="string" name="pm" />
+  <java-symbol type="string" name="policydesc_disableCamera" />
+  <java-symbol type="string" name="policydesc_encryptedStorage" />
+  <java-symbol type="string" name="policydesc_expirePassword" />
+  <java-symbol type="string" name="policydesc_forceLock" />
+  <java-symbol type="string" name="policydesc_limitPassword" />
+  <java-symbol type="string" name="policydesc_resetPassword" />
+  <java-symbol type="string" name="policydesc_setGlobalProxy" />
+  <java-symbol type="string" name="policydesc_watchLogin" />
+  <java-symbol type="string" name="policydesc_wipeData" />
+  <java-symbol type="string" name="policydesc_disableKeyguardWidgets" />
+  <java-symbol type="string" name="policylab_disableCamera" />
+  <java-symbol type="string" name="policylab_encryptedStorage" />
+  <java-symbol type="string" name="policylab_expirePassword" />
+  <java-symbol type="string" name="policylab_forceLock" />
+  <java-symbol type="string" name="policylab_limitPassword" />
+  <java-symbol type="string" name="policylab_resetPassword" />
+  <java-symbol type="string" name="policylab_setGlobalProxy" />
+  <java-symbol type="string" name="policylab_watchLogin" />
+  <java-symbol type="string" name="policylab_wipeData" />
+  <java-symbol type="string" name="policylab_disableKeyguardWidgets" />
+  <java-symbol type="string" name="postalTypeCustom" />
+  <java-symbol type="string" name="postalTypeHome" />
+  <java-symbol type="string" name="postalTypeOther" />
+  <java-symbol type="string" name="postalTypeWork" />
+  <java-symbol type="string" name="power_off" />
+  <java-symbol type="string" name="preposition_for_date" />
+  <java-symbol type="string" name="preposition_for_time" />
+  <java-symbol type="string" name="progress_erasing" />
+  <java-symbol type="string" name="progress_unmounting" />
+  <java-symbol type="string" name="reboot_safemode_confirm" />
+  <java-symbol type="string" name="reboot_safemode_title" />
+  <java-symbol type="string" name="relationTypeAssistant" />
+  <java-symbol type="string" name="relationTypeBrother" />
+  <java-symbol type="string" name="relationTypeChild" />
+  <java-symbol type="string" name="relationTypeDomesticPartner" />
+  <java-symbol type="string" name="relationTypeFather" />
+  <java-symbol type="string" name="relationTypeFriend" />
+  <java-symbol type="string" name="relationTypeManager" />
+  <java-symbol type="string" name="relationTypeMother" />
+  <java-symbol type="string" name="relationTypeParent" />
+  <java-symbol type="string" name="relationTypePartner" />
+  <java-symbol type="string" name="relationTypeReferredBy" />
+  <java-symbol type="string" name="relationTypeRelative" />
+  <java-symbol type="string" name="relationTypeSister" />
+  <java-symbol type="string" name="relationTypeSpouse" />
+  <java-symbol type="string" name="relative_time" />
+  <java-symbol type="string" name="reset" />
+  <java-symbol type="string" name="ringtone_default" />
+  <java-symbol type="string" name="ringtone_default_with_actual" />
+  <java-symbol type="string" name="ringtone_picker_title" />
+  <java-symbol type="string" name="ringtone_silent" />
+  <java-symbol type="string" name="ringtone_unknown" />
+  <java-symbol type="string" name="roamingText0" />
+  <java-symbol type="string" name="roamingText1" />
+  <java-symbol type="string" name="roamingText10" />
+  <java-symbol type="string" name="roamingText11" />
+  <java-symbol type="string" name="roamingText12" />
+  <java-symbol type="string" name="roamingText2" />
+  <java-symbol type="string" name="roamingText3" />
+  <java-symbol type="string" name="roamingText4" />
+  <java-symbol type="string" name="roamingText5" />
+  <java-symbol type="string" name="roamingText6" />
+  <java-symbol type="string" name="roamingText7" />
+  <java-symbol type="string" name="roamingText8" />
+  <java-symbol type="string" name="roamingText9" />
+  <java-symbol type="string" name="roamingTextSearching" />
+  <java-symbol type="string" name="same_month_md1_md2" />
+  <java-symbol type="string" name="same_month_md1_time1_md2_time2" />
+  <java-symbol type="string" name="same_month_mdy1_mdy2" />
+  <java-symbol type="string" name="same_month_mdy1_time1_mdy2_time2" />
+  <java-symbol type="string" name="same_month_wday1_md1_time1_wday2_md2_time2" />
+  <java-symbol type="string" name="same_month_wday1_md1_wday2_md2" />
+  <java-symbol type="string" name="same_month_wday1_mdy1_time1_wday2_mdy2_time2" />
+  <java-symbol type="string" name="same_month_wday1_mdy1_wday2_mdy2" />
+  <java-symbol type="string" name="same_year_md1_md2" />
+  <java-symbol type="string" name="same_year_md1_time1_md2_time2" />
+  <java-symbol type="string" name="same_year_mdy1_mdy2" />
+  <java-symbol type="string" name="same_year_mdy1_time1_mdy2_time2" />
+  <java-symbol type="string" name="same_year_wday1_md1_time1_wday2_md2_time2" />
+  <java-symbol type="string" name="same_year_wday1_md1_wday2_md2" />
+  <java-symbol type="string" name="same_year_wday1_mdy1_time1_wday2_mdy2_time2" />
+  <java-symbol type="string" name="same_year_wday1_mdy1_wday2_mdy2" />
+  <java-symbol type="string" name="save_password_label" />
+  <java-symbol type="string" name="save_password_message" />
+  <java-symbol type="string" name="save_password_never" />
+  <java-symbol type="string" name="save_password_notnow" />
+  <java-symbol type="string" name="save_password_remember" />
+  <java-symbol type="string" name="sendText" />
+  <java-symbol type="string" name="sending" />
+  <java-symbol type="string" name="serviceClassData" />
+  <java-symbol type="string" name="serviceClassDataAsync" />
+  <java-symbol type="string" name="serviceClassDataSync" />
+  <java-symbol type="string" name="serviceClassFAX" />
+  <java-symbol type="string" name="serviceClassPAD" />
+  <java-symbol type="string" name="serviceClassPacket" />
+  <java-symbol type="string" name="serviceClassSMS" />
+  <java-symbol type="string" name="serviceClassVoice" />
+  <java-symbol type="string" name="serviceDisabled" />
+  <java-symbol type="string" name="serviceEnabled" />
+  <java-symbol type="string" name="serviceEnabledFor" />
+  <java-symbol type="string" name="serviceErased" />
+  <java-symbol type="string" name="serviceNotProvisioned" />
+  <java-symbol type="string" name="serviceRegistered" />
+  <java-symbol type="string" name="setup_autofill" />
+  <java-symbol type="string" name="share" />
+  <java-symbol type="string" name="shareactionprovider_share_with" />
+  <java-symbol type="string" name="shareactionprovider_share_with_application" />
+  <java-symbol type="string" name="short_format_month" />
+  <java-symbol type="string" name="shutdown_confirm" />
+  <java-symbol type="string" name="shutdown_confirm_question" />
+  <java-symbol type="string" name="shutdown_progress" />
+  <java-symbol type="string" name="sim_added_message" />
+  <java-symbol type="string" name="sim_added_title" />
+  <java-symbol type="string" name="sim_removed_message" />
+  <java-symbol type="string" name="sim_removed_title" />
+  <java-symbol type="string" name="sim_restart_button" />
+  <java-symbol type="string" name="sipAddressTypeCustom" />
+  <java-symbol type="string" name="sipAddressTypeHome" />
+  <java-symbol type="string" name="sipAddressTypeOther" />
+  <java-symbol type="string" name="sipAddressTypeWork" />
+  <java-symbol type="string" name="sms_control_message" />
+  <java-symbol type="string" name="sms_control_title" />
+  <java-symbol type="string" name="sms_control_no" />
+  <java-symbol type="string" name="sms_control_yes" />
+  <java-symbol type="string" name="sms_premium_short_code_confirm_message" />
+  <java-symbol type="string" name="sms_premium_short_code_confirm_title" />
+  <java-symbol type="string" name="sms_short_code_confirm_allow" />
+  <java-symbol type="string" name="sms_short_code_confirm_deny" />
+  <java-symbol type="string" name="sms_short_code_confirm_message" />
+  <java-symbol type="string" name="sms_short_code_confirm_report" />
+  <java-symbol type="string" name="sms_short_code_confirm_title" />
+  <java-symbol type="string" name="submit" />
+  <java-symbol type="string" name="sync_binding_label" />
+  <java-symbol type="string" name="sync_do_nothing" />
+  <java-symbol type="string" name="sync_really_delete" />
+  <java-symbol type="string" name="sync_too_many_deletes_desc" />
+  <java-symbol type="string" name="sync_undo_deletes" />
+  <java-symbol type="string" name="terabyteShort" />
+  <java-symbol type="string" name="text_copied" />
+  <java-symbol type="string" name="time1_time2" />
+  <java-symbol type="string" name="time_date" />
+  <java-symbol type="string" name="time_of_day" />
+  <java-symbol type="string" name="time_picker_decrement_hour_button" />
+  <java-symbol type="string" name="time_picker_decrement_minute_button" />
+  <java-symbol type="string" name="time_picker_decrement_set_am_button" />
+  <java-symbol type="string" name="time_picker_dialog_title" />
+  <java-symbol type="string" name="time_picker_increment_hour_button" />
+  <java-symbol type="string" name="time_picker_increment_minute_button" />
+  <java-symbol type="string" name="time_picker_increment_set_pm_button" />
+  <java-symbol type="string" name="time_picker_separator" />
+  <java-symbol type="string" name="time_wday" />
+  <java-symbol type="string" name="time_wday_date" />
+  <java-symbol type="string" name="today" />
+  <java-symbol type="string" name="tomorrow" />
+  <java-symbol type="string" name="twelve_hour_time_format" />
+  <java-symbol type="string" name="twenty_four_hour_time_format" />
+  <java-symbol type="string" name="upload_file" />
+  <java-symbol type="string" name="volume_alarm" />
+  <java-symbol type="string" name="volume_icon_description_bluetooth" />
+  <java-symbol type="string" name="volume_icon_description_incall" />
+  <java-symbol type="string" name="volume_icon_description_media" />
+  <java-symbol type="string" name="volume_icon_description_notification" />
+  <java-symbol type="string" name="volume_icon_description_ringer" />
+  <java-symbol type="string" name="wait" />
+  <java-symbol type="string" name="wday1_date1_time1_wday2_date2_time2" />
+  <java-symbol type="string" name="wday1_date1_wday2_date2" />
+  <java-symbol type="string" name="wday_date" />
+  <java-symbol type="string" name="web_user_agent" />
+  <java-symbol type="string" name="web_user_agent_target_content" />
+  <java-symbol type="string" name="webpage_unresponsive" />
+  <java-symbol type="string" name="whichApplication" />
+  <java-symbol type="string" name="wifi_available_sign_in" />
+  <java-symbol type="string" name="wifi_available_sign_in_detailed" />
+  <java-symbol type="string" name="wifi_p2p_dialog_title" />
+  <java-symbol type="string" name="wifi_p2p_enabled_notification_message" />
+  <java-symbol type="string" name="wifi_p2p_enabled_notification_title" />
+  <java-symbol type="string" name="wifi_p2p_failed_message" />
+  <java-symbol type="string" name="wifi_p2p_from_message" />
+  <java-symbol type="string" name="wifi_p2p_invitation_sent_title" />
+  <java-symbol type="string" name="wifi_p2p_invitation_to_connect_title" />
+  <java-symbol type="string" name="wifi_p2p_show_pin_message" />
+  <java-symbol type="string" name="wifi_p2p_to_message" />
+  <java-symbol type="string" name="wifi_p2p_turnon_message" />
+  <java-symbol type="string" name="wifi_tether_configure_ssid_default" />
+  <java-symbol type="string" name="wifi_watchdog_network_disabled" />
+  <java-symbol type="string" name="wifi_watchdog_network_disabled_detailed" />
+  <java-symbol type="string" name="yesterday" />
+  <java-symbol type="string" name="imei" />
+  <java-symbol type="string" name="meid" />
+  <java-symbol type="string" name="granularity_label_character" />
+  <java-symbol type="string" name="granularity_label_word" />
+  <java-symbol type="string" name="granularity_label_link" />
+  <java-symbol type="string" name="granularity_label_line" />
+  <java-symbol type="string" name="default_audio_route_name" />
+  <java-symbol type="string" name="default_audio_route_name_headphones" />
+  <java-symbol type="string" name="default_audio_route_name_dock_speakers" />
+  <java-symbol type="string" name="default_audio_route_name_hdmi" />
+  <java-symbol type="string" name="default_audio_route_category_name" />
+
+  <java-symbol type="plurals" name="abbrev_in_num_days" />
+  <java-symbol type="plurals" name="abbrev_in_num_hours" />
+  <java-symbol type="plurals" name="abbrev_in_num_minutes" />
+  <java-symbol type="plurals" name="abbrev_in_num_seconds" />
+  <java-symbol type="plurals" name="abbrev_num_days_ago" />
+  <java-symbol type="plurals" name="abbrev_num_hours_ago" />
+  <java-symbol type="plurals" name="abbrev_num_minutes_ago" />
+  <java-symbol type="plurals" name="abbrev_num_seconds_ago" />
+  <java-symbol type="plurals" name="in_num_days" />
+  <java-symbol type="plurals" name="in_num_hours" />
+  <java-symbol type="plurals" name="in_num_minutes" />
+  <java-symbol type="plurals" name="in_num_seconds" />
+  <java-symbol type="plurals" name="last_num_days" />
+  <java-symbol type="plurals" name="matches_found" />
+  <java-symbol type="plurals" name="num_days_ago" />
+  <java-symbol type="plurals" name="num_hours_ago" />
+  <java-symbol type="plurals" name="num_minutes_ago" />
+  <java-symbol type="plurals" name="num_seconds_ago" />
+
+  <java-symbol type="array" name="carrier_properties" />
+  <java-symbol type="array" name="config_data_usage_network_types" />
+  <java-symbol type="array" name="config_sms_enabled_locking_shift_tables" />
+  <java-symbol type="array" name="config_sms_enabled_single_shift_tables" />
+  <java-symbol type="array" name="config_twoDigitNumberPattern" />
+  <java-symbol type="array" name="networkAttributes" />
+  <java-symbol type="array" name="preloaded_color_state_lists" />
+  <java-symbol type="array" name="preloaded_drawables" />
+  <java-symbol type="array" name="special_locale_codes" />
+  <java-symbol type="array" name="special_locale_names" />
+  <java-symbol type="array" name="config_masterVolumeRamp" />
+  <java-symbol type="array" name="config_cdma_dun_supported_types" />
+
+  <java-symbol type="drawable" name="default_wallpaper" />
+  <java-symbol type="drawable" name="indicator_input_error" />
+  <java-symbol type="drawable" name="overscroll_edge" />
+  <java-symbol type="drawable" name="overscroll_glow" />
+  <java-symbol type="drawable" name="popup_bottom_dark" />
+  <java-symbol type="drawable" name="popup_bottom_bright" />
+  <java-symbol type="drawable" name="popup_bottom_medium" />
+  <java-symbol type="drawable" name="popup_center_dark" />
+  <java-symbol type="drawable" name="popup_center_bright" />
+  <java-symbol type="drawable" name="popup_full_dark" />
+  <java-symbol type="drawable" name="popup_full_bright" />
+  <java-symbol type="drawable" name="popup_top_dark" />
+  <java-symbol type="drawable" name="popup_top_bright" />
+  <java-symbol type="drawable" name="search_spinner" />
+  <java-symbol type="drawable" name="sym_app_on_sd_unavailable_icon" />
+  <java-symbol type="drawable" name="text_edit_side_paste_window" />
+  <java-symbol type="drawable" name="text_edit_paste_window" />
+  <java-symbol type="drawable" name="btn_check_off" />
+  <java-symbol type="drawable" name="btn_code_lock_default_holo" />
+  <java-symbol type="drawable" name="btn_code_lock_touched_holo" />
+  <java-symbol type="drawable" name="clock_dial" />
+  <java-symbol type="drawable" name="clock_hand_hour" />
+  <java-symbol type="drawable" name="clock_hand_minute" />
+  <java-symbol type="drawable" name="emo_im_angel" />
+  <java-symbol type="drawable" name="emo_im_cool" />
+  <java-symbol type="drawable" name="emo_im_crying" />
+  <java-symbol type="drawable" name="emo_im_embarrassed" />
+  <java-symbol type="drawable" name="emo_im_foot_in_mouth" />
+  <java-symbol type="drawable" name="emo_im_happy" />
+  <java-symbol type="drawable" name="emo_im_kissing" />
+  <java-symbol type="drawable" name="emo_im_laughing" />
+  <java-symbol type="drawable" name="emo_im_lips_are_sealed" />
+  <java-symbol type="drawable" name="emo_im_money_mouth" />
+  <java-symbol type="drawable" name="emo_im_sad" />
+  <java-symbol type="drawable" name="emo_im_surprised" />
+  <java-symbol type="drawable" name="emo_im_tongue_sticking_out" />
+  <java-symbol type="drawable" name="emo_im_undecided" />
+  <java-symbol type="drawable" name="emo_im_winking" />
+  <java-symbol type="drawable" name="emo_im_wtf" />
+  <java-symbol type="drawable" name="emo_im_yelling" />
+  <java-symbol type="drawable" name="expander_close_holo_dark" />
+  <java-symbol type="drawable" name="expander_open_holo_dark" />
+  <java-symbol type="drawable" name="ic_audio_alarm" />
+  <java-symbol type="drawable" name="ic_audio_alarm_mute" />
+  <java-symbol type="drawable" name="ic_audio_bt" />
+  <java-symbol type="drawable" name="ic_audio_bt_mute" />
+  <java-symbol type="drawable" name="ic_audio_notification" />
+  <java-symbol type="drawable" name="ic_audio_notification_mute" />
+  <java-symbol type="drawable" name="ic_audio_phone" />
+  <java-symbol type="drawable" name="ic_audio_ring_notif" />
+  <java-symbol type="drawable" name="ic_audio_ring_notif_mute" />
+  <java-symbol type="drawable" name="ic_audio_ring_notif_vibrate" />
+  <java-symbol type="drawable" name="ic_audio_vol" />
+  <java-symbol type="drawable" name="ic_audio_vol_mute" />
+  <java-symbol type="drawable" name="ic_bullet_key_permission" />
+  <java-symbol type="drawable" name="ic_contact_picture" />
+  <java-symbol type="drawable" name="ic_dialog_usb" />
+  <java-symbol type="drawable" name="ic_emergency" />
+  <java-symbol type="drawable" name="ic_media_stop" />
+  <java-symbol type="drawable" name="ic_text_dot" />
+  <java-symbol type="drawable" name="indicator_code_lock_drag_direction_green_up" />
+  <java-symbol type="drawable" name="indicator_code_lock_drag_direction_red_up" />
+  <java-symbol type="drawable" name="indicator_code_lock_point_area_default_holo" />
+  <java-symbol type="drawable" name="indicator_code_lock_point_area_green_holo" />
+  <java-symbol type="drawable" name="indicator_code_lock_point_area_red_holo" />
+  <java-symbol type="drawable" name="jog_dial_arrow_long_left_green" />
+  <java-symbol type="drawable" name="jog_dial_arrow_long_right_red" />
+  <java-symbol type="drawable" name="jog_dial_arrow_short_left_and_right" />
+  <java-symbol type="drawable" name="jog_dial_bg" />
+  <java-symbol type="drawable" name="jog_dial_dimple" />
+  <java-symbol type="drawable" name="jog_dial_dimple_dim" />
+  <java-symbol type="drawable" name="jog_tab_bar_left_generic" />
+  <java-symbol type="drawable" name="jog_tab_bar_right_generic" />
+  <java-symbol type="drawable" name="jog_tab_left_generic" />
+  <java-symbol type="drawable" name="jog_tab_right_generic" />
+  <java-symbol type="drawable" name="jog_tab_target_gray" />
+  <java-symbol type="drawable" name="picture_emergency" />
+  <java-symbol type="drawable" name="platlogo" />
+  <java-symbol type="drawable" name="platlogo_alt" />
+  <java-symbol type="drawable" name="stat_notify_sync_error" />
+  <java-symbol type="drawable" name="stat_notify_wifi_in_range" />
+  <java-symbol type="drawable" name="stat_sys_gps_on" />
+  <java-symbol type="drawable" name="stat_sys_tether_wifi" />
+  <java-symbol type="drawable" name="status_bar_background" />
+  <java-symbol type="drawable" name="sym_keyboard_shift" />
+  <java-symbol type="drawable" name="sym_keyboard_shift_locked" />
+  <java-symbol type="drawable" name="tab_bottom_left" />
+  <java-symbol type="drawable" name="tab_bottom_left_v4" />
+  <java-symbol type="drawable" name="tab_bottom_right" />
+  <java-symbol type="drawable" name="tab_bottom_right_v4" />
+  <java-symbol type="drawable" name="tab_indicator_v4" />
+  <java-symbol type="drawable" name="text_select_handle_left" />
+  <java-symbol type="drawable" name="text_select_handle_middle" />
+  <java-symbol type="drawable" name="text_select_handle_right" />
+  <java-symbol type="drawable" name="unknown_image" />
+  <java-symbol type="drawable" name="unlock_default" />
+  <java-symbol type="drawable" name="unlock_halo" />
+  <java-symbol type="drawable" name="unlock_ring" />
+  <java-symbol type="drawable" name="unlock_wave" />
+  <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_action_assist_generic" />
+  <java-symbol type="drawable" name="notification_bg" />
+  <java-symbol type="drawable" name="notification_bg_low" />
+  <java-symbol type="drawable" name="notification_template_icon_bg" />
+  <java-symbol type="drawable" name="notification_template_icon_low_bg" />
+  <java-symbol type="drawable" name="ic_lockscreen_unlock_phantom" />
+  <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
+  <java-symbol type="drawable" name="ic_media_route_disabled_holo_dark" />
+
+  <java-symbol type="layout" name="action_bar_home" />
+  <java-symbol type="layout" name="action_bar_title_item" />
+  <java-symbol type="layout" name="action_menu_item_layout" />
+  <java-symbol type="layout" name="action_menu_layout" />
+  <java-symbol type="layout" name="action_mode_close_item" />
+  <java-symbol type="layout" name="alert_dialog" />
+  <java-symbol type="layout" name="choose_account" />
+  <java-symbol type="layout" name="choose_account_row" />
+  <java-symbol type="layout" name="choose_account_type" />
+  <java-symbol type="layout" name="choose_type_and_account" />
+  <java-symbol type="layout" name="grant_credentials_permission" />
+  <java-symbol type="layout" name="number_picker" />
+  <java-symbol type="layout" name="permissions_package_list_item" />
+  <java-symbol type="layout" name="popup_menu_item_layout" />
+  <java-symbol type="layout" name="remote_views_adapter_default_loading_view" />
+  <java-symbol type="layout" name="search_bar" />
+  <java-symbol type="layout" name="search_dropdown_item_icons_2line" />
+  <java-symbol type="layout" name="search_view" />
+  <java-symbol type="layout" name="select_dialog" />
+  <java-symbol type="layout" name="simple_dropdown_hint" />
+  <java-symbol type="layout" name="status_bar_latest_event_content" />
+  <java-symbol type="layout" name="status_bar_latest_event_ticker" />
+  <java-symbol type="layout" name="status_bar_latest_event_ticker_large_icon" />
+  <java-symbol type="layout" name="text_edit_action_popup_text" />
+  <java-symbol type="layout" name="text_drag_thumbnail" />
+  <java-symbol type="layout" name="typing_filter" />
+  <java-symbol type="layout" name="activity_chooser_view" />
+  <java-symbol type="layout" name="activity_chooser_view_list_item" />
+  <java-symbol type="layout" name="activity_list" />
+  <java-symbol type="layout" name="activity_list_item_2" />
+  <java-symbol type="layout" name="alert_dialog_progress" />
+  <java-symbol type="layout" name="always_use_checkbox" />
+  <java-symbol type="layout" name="app_permission_item" />
+  <java-symbol type="layout" name="app_permission_item_old" />
+  <java-symbol type="layout" name="app_perms_summary" />
+  <java-symbol type="layout" name="calendar_view" />
+  <java-symbol type="layout" name="character_picker" />
+  <java-symbol type="layout" name="character_picker_button" />
+  <java-symbol type="layout" name="date_picker" />
+  <java-symbol type="layout" name="date_picker_dialog" />
+  <java-symbol type="layout" name="expanded_menu_layout" />
+  <java-symbol type="layout" name="fragment_bread_crumb_item" />
+  <java-symbol type="layout" name="fragment_bread_crumbs" />
+  <java-symbol type="layout" name="heavy_weight_switcher" />
+  <java-symbol type="layout" name="icon_menu_item_layout" />
+  <java-symbol type="layout" name="icon_menu_layout" />
+  <java-symbol type="layout" name="input_method" />
+  <java-symbol type="layout" name="input_method_extract_view" />
+  <java-symbol type="layout" name="input_method_switch_dialog_title" />
+  <java-symbol type="layout" name="js_prompt" />
+  <java-symbol type="layout" name="list_content_simple" />
+  <java-symbol type="layout" name="list_menu_item_checkbox" />
+  <java-symbol type="layout" name="list_menu_item_icon" />
+  <java-symbol type="layout" name="list_menu_item_layout" />
+  <java-symbol type="layout" name="list_menu_item_radio" />
+  <java-symbol type="layout" name="locale_picker_item" />
+  <java-symbol type="layout" name="media_controller" />
+  <java-symbol type="layout" name="overlay_display_window" />
+  <java-symbol type="layout" name="preference" />
+  <java-symbol type="layout" name="preference_header_item" />
+  <java-symbol type="layout" name="preference_list_content" />
+  <java-symbol type="layout" name="preference_list_content_single" />
+  <java-symbol type="layout" name="preference_list_fragment" />
+  <java-symbol type="layout" name="preference_widget_seekbar" />
+  <java-symbol type="layout" name="progress_dialog" />
+  <java-symbol type="layout" name="resolve_list_item" />
+  <java-symbol type="layout" name="seekbar_dialog" />
+  <java-symbol type="layout" name="select_dialog_singlechoice_holo" />
+  <java-symbol type="layout" name="ssl_certificate" />
+  <java-symbol type="layout" name="tab_content" />
+  <java-symbol type="layout" name="tab_indicator_holo" />
+  <java-symbol type="layout" name="textview_hint" />
+  <java-symbol type="layout" name="time_picker" />
+  <java-symbol type="layout" name="time_picker_dialog" />
+  <java-symbol type="layout" name="transient_notification" />
+  <java-symbol type="layout" name="volume_adjust" />
+  <java-symbol type="layout" name="volume_adjust_item" />
+  <java-symbol type="layout" name="web_text_view_dropdown" />
+  <java-symbol type="layout" name="webview_find" />
+  <java-symbol type="layout" name="webview_select_singlechoice" />
+  <java-symbol type="layout" name="wifi_p2p_dialog" />
+  <java-symbol type="layout" name="wifi_p2p_dialog_row" />
+  <java-symbol type="layout" name="zoom_container" />
+  <java-symbol type="layout" name="zoom_controls" />
+  <java-symbol type="layout" name="zoom_magnify" />
+  <java-symbol type="layout" name="notification_action" />
+  <java-symbol type="layout" name="notification_action_tombstone" />
+  <java-symbol type="layout" name="notification_intruder_content" />
+  <java-symbol type="layout" name="notification_template_base" />
+  <java-symbol type="layout" name="notification_template_big_base" />
+  <java-symbol type="layout" name="notification_template_big_picture" />
+  <java-symbol type="layout" name="notification_template_big_text" />
+  <java-symbol type="layout" name="notification_template_part_time" />
+  <java-symbol type="layout" name="notification_template_part_chronometer" />
+  <java-symbol type="layout" name="notification_template_inbox" />
+  <java-symbol type="layout" name="keyguard_multi_user_avatar" />
+  <java-symbol type="layout" name="keyguard_multi_user_selector_widget" />
+
+  <java-symbol type="anim" name="slide_in_child_bottom" />
+  <java-symbol type="anim" name="slide_in_right" />
+  <java-symbol type="anim" name="slide_out_left" />
+
+  <java-symbol type="menu" name="webview_copy" />
+  <java-symbol type="menu" name="webview_find" />
+
+  <java-symbol type="xml" name="password_kbd_qwerty" />
+  <java-symbol type="xml" name="autotext" />
+  <java-symbol type="xml" name="eri" />
+  <java-symbol type="xml" name="password_kbd_numeric" />
+  <java-symbol type="xml" name="password_kbd_qwerty_shifted" />
+  <java-symbol type="xml" name="password_kbd_symbols" />
+  <java-symbol type="xml" name="password_kbd_symbols_shift" />
+  <java-symbol type="xml" name="power_profile" />
+  <java-symbol type="xml" name="time_zones_by_country" />
+  <java-symbol type="xml" name="sms_short_codes" />
+
+  <java-symbol type="raw" name="accessibility_gestures" />
+  <java-symbol type="raw" name="incognito_mode_start_page" />
+  <java-symbol type="raw" name="loaderror" />
+  <java-symbol type="raw" name="nodomain" />
+
+  <java-symbol type="style" name="Animation.DropDownUp" />
+  <java-symbol type="style" name="Animation.DropDownDown" />
+  <java-symbol type="style" name="Animation.PopupWindow" />
+  <java-symbol type="style" name="Animation.TypingFilter" />
+  <java-symbol type="style" name="Animation.TypingFilterRestore" />
+  <java-symbol type="style" name="Animation.Dream" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.Alert" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" />
+  <java-symbol type="style" name="Theme.Dialog.Alert" />
+  <java-symbol type="style" name="Theme.Holo.Dialog.Alert" />
+  <java-symbol type="style" name="Theme.Holo.Light.Dialog.Alert" />
+  <java-symbol type="style" name="ActiveWallpaperSettings" />
+  <java-symbol type="style" name="Animation.InputMethodFancy" />
+  <java-symbol type="style" name="Animation.Wallpaper" />
+  <java-symbol type="style" name="Animation.ZoomButtons" />
+  <java-symbol type="style" name="PreviewWallpaperSettings" />
+  <java-symbol type="style" name="TextAppearance.SlidingTabActive" />
+  <java-symbol type="style" name="TextAppearance.SlidingTabNormal" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.NoFrame" />
+  <java-symbol type="style" name="Theme.IconMenu" />
+  <java-symbol type="style" name="Theme.Panel.Volume" />
+
+  <java-symbol type="attr" name="mediaRouteButtonStyle" />
+  <java-symbol type="attr" name="externalRouteEnabledDrawable" />
+  <java-symbol type="id" name="extended_settings" />
+  <java-symbol type="id" name="check" />
+  <java-symbol type="id" name="volume_slider" />
+  <java-symbol type="id" name="volume_icon" />
+  <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
+  <java-symbol type="layout" name="media_route_chooser_layout" />
+  <java-symbol type="layout" name="media_route_list_item_top_header" />
+  <java-symbol type="layout" name="media_route_list_item_section_header" />
+  <java-symbol type="layout" name="media_route_list_item" />
+  <java-symbol type="layout" name="media_route_list_item_checkable" />
+  <java-symbol type="layout" name="media_route_list_item_collapse_group" />
+  <java-symbol type="string" name="bluetooth_a2dp_audio_route_name" />
+
+  <!-- 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="lock_screen_wallpaper_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="anim" name="keyguard_security_animate_in" />
+  <java-symbol type="anim" name="keyguard_security_animate_out" />
+  <java-symbol type="anim" name="keyguard_security_fade_in" />
+  <java-symbol type="anim" name="keyguard_security_fade_out" />
+  <java-symbol type="array" name="config_keyboardTapVibePattern" />
+  <java-symbol type="array" name="config_longPressVibePattern" />
+  <java-symbol type="array" name="config_safeModeDisabledVibePattern" />
+  <java-symbol type="array" name="config_safeModeEnabledVibePattern" />
+  <java-symbol type="array" name="config_virtualKeyVibePattern" />
+  <java-symbol type="array" name="lockscreen_targets_when_silent" />
+  <java-symbol type="array" name="lockscreen_targets_when_soundon" />
+  <java-symbol type="array" name="lockscreen_targets_with_camera" />
+  <java-symbol type="attr" name="actionModePopupWindowStyle" />
+  <java-symbol type="attr" name="dialogCustomTitleDecorLayout" />
+  <java-symbol type="attr" name="dialogTitleDecorLayout" />
+  <java-symbol type="attr" name="dialogTitleIconsDecorLayout" />
+  <java-symbol type="bool" name="config_allowAllRotations" />
+  <java-symbol type="bool" name="config_annoy_dianne" />
+  <java-symbol type="bool" name="config_carDockEnablesAccelerometer" />
+  <java-symbol type="bool" name="config_deskDockEnablesAccelerometer" />
+  <java-symbol type="bool" name="config_disableMenuKeyInLockScreen" />
+  <java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
+  <java-symbol type="bool" name="config_enableLockScreenRotation" />
+  <java-symbol type="bool" name="config_lidControlsSleep" />
+  <java-symbol type="bool" name="config_reverseDefaultRotation" />
+  <java-symbol type="bool" name="config_showNavigationBar" />
+  <java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
+  <java-symbol type="dimen" name="navigation_bar_height" />
+  <java-symbol type="dimen" name="navigation_bar_height_landscape" />
+  <java-symbol type="dimen" name="navigation_bar_width" />
+  <java-symbol type="dimen" name="status_bar_height" />
+  <java-symbol type="dimen" name="kg_widget_page_padding" />
+  <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" />
+  <java-symbol type="drawable" name="ic_jog_dial_vibrate_on" />
+  <java-symbol type="drawable" name="ic_lock_airplane_mode" />
+  <java-symbol type="drawable" name="ic_lock_airplane_mode_off" />
+  <java-symbol type="drawable" name="ic_menu_cc" />
+  <java-symbol type="drawable" name="jog_tab_bar_left_unlock" />
+  <java-symbol type="drawable" name="jog_tab_bar_right_sound_off" />
+  <java-symbol type="drawable" name="jog_tab_bar_right_sound_on" />
+  <java-symbol type="drawable" name="jog_tab_left_unlock" />
+  <java-symbol type="drawable" name="jog_tab_right_sound_off" />
+  <java-symbol type="drawable" name="jog_tab_right_sound_on" />
+  <java-symbol type="drawable" name="jog_tab_target_green" />
+  <java-symbol type="drawable" name="jog_tab_target_yellow" />
+  <java-symbol type="drawable" name="magnified_region_frame" />
+  <java-symbol type="drawable" name="menu_background" />
+  <java-symbol type="drawable" name="stat_sys_secure" />
+  <java-symbol type="drawable" name="kg_widget_overscroll_layer_left" />
+  <java-symbol type="drawable" name="kg_widget_overscroll_layer_right" />
+  <java-symbol type="id" name="action_mode_bar_stub" />
+  <java-symbol type="id" name="alarm_status" />
+  <java-symbol type="id" name="backspace" />
+  <java-symbol type="id" name="button0" />
+  <java-symbol type="id" name="button4" />
+  <java-symbol type="id" name="button5" />
+  <java-symbol type="id" name="button6" />
+  <java-symbol type="id" name="button7" />
+  <java-symbol type="id" name="carrier" />
+  <java-symbol type="id" name="date" />
+  <java-symbol type="id" name="eight" />
+  <java-symbol type="id" name="emergencyCallButton" />
+  <java-symbol type="id" name="face_unlock_area_view" />
+  <java-symbol type="id" name="five" />
+  <java-symbol type="id" name="forgotPatternButton" />
+  <java-symbol type="id" name="four" />
+  <java-symbol type="id" name="headerText" />
+  <java-symbol type="id" name="icon_menu_presenter" />
+  <java-symbol type="id" name="instructions" />
+  <java-symbol type="id" name="keyboard" />
+  <java-symbol type="id" name="list_menu_presenter" />
+  <java-symbol type="id" name="lockPattern" />
+  <java-symbol type="id" name="lock_screen" />
+  <java-symbol type="id" name="login" />
+  <java-symbol type="id" name="nine" />
+  <java-symbol type="id" name="no_applications_message" />
+  <java-symbol type="id" name="ok" />
+  <java-symbol type="id" name="one" />
+  <java-symbol type="id" name="option1" />
+  <java-symbol type="id" name="option2" />
+  <java-symbol type="id" name="option3" />
+  <java-symbol type="id" name="password" />
+  <java-symbol type="id" name="passwordEntry" />
+  <java-symbol type="id" name="pinDel" />
+  <java-symbol type="id" name="pinDisplay" />
+  <java-symbol type="id" name="owner_info" />
+  <java-symbol type="id" name="pukDel" />
+  <java-symbol type="id" name="pukDisplay" />
+  <java-symbol type="id" name="right_icon" />
+  <java-symbol type="id" name="seven" />
+  <java-symbol type="id" name="six" />
+  <java-symbol type="id" name="status" />
+  <java-symbol type="id" name="status1" />
+  <java-symbol type="id" name="switch_ime_button" />
+  <java-symbol type="id" name="three" />
+  <java-symbol type="id" name="title_container" />
+  <java-symbol type="id" name="topHeader" />
+  <java-symbol type="id" name="transport" />
+  <java-symbol type="id" name="transport_bg_protect" />
+  <java-symbol type="id" name="two" />
+  <java-symbol type="id" name="unlock_widget" />
+  <java-symbol type="id" name="zero" />
+  <java-symbol type="id" name="keyguard_message_area" />
+  <java-symbol type="id" name="keyguard_click_area" />
+  <java-symbol type="id" name="keyguard_selector_view" />
+  <java-symbol type="id" name="keyguard_pattern_view" />
+  <java-symbol type="id" name="keyguard_password_view" />
+  <java-symbol type="id" name="keyguard_face_unlock_view" />
+  <java-symbol type="id" name="keyguard_sim_pin_view" />
+  <java-symbol type="id" name="keyguard_sim_puk_view" />
+  <java-symbol type="id" name="keyguard_account_view" />
+  <java-symbol type="id" name="app_widget_container" />
+  <java-symbol type="id" name="view_flipper" />
+  <java-symbol type="id" name="emergency_call_button" />
+  <java-symbol type="id" name="keyguard_host_view" />
+  <java-symbol type="id" name="delete_button" />
+  <java-symbol type="id" name="lockPatternView" />
+  <java-symbol type="id" name="forgot_password_button" />
+  <java-symbol type="id" name="glow_pad_view" />
+  <java-symbol type="id" name="sim_pin_entry" />
+  <java-symbol type="id" name="delete_button" />
+  <java-symbol type="id" name="sim_puk_entry" />
+  <java-symbol type="id" name="sim_pin_entry" />
+  <java-symbol type="id" name="puk_delete_button" />
+  <java-symbol type="id" name="pin_delete_button" />
+  <java-symbol type="id" name="keyguard_user_avatar" />
+  <java-symbol type="id" name="keyguard_user_name" />
+  <java-symbol type="id" name="keyguard_active_user" />
+  <java-symbol type="id" name="keyguard_inactive_users" />
+  <java-symbol type="integer" name="config_carDockRotation" />
+  <java-symbol type="integer" name="config_defaultUiModeType" />
+  <java-symbol type="integer" name="config_deskDockRotation" />
+  <java-symbol type="integer" name="config_lidKeyboardAccessibility" />
+  <java-symbol type="integer" name="config_lidNavigationAccessibility" />
+  <java-symbol type="integer" name="config_lidOpenRotation" />
+  <java-symbol type="integer" name="config_longPressOnHomeBehavior" />
+  <java-symbol type="integer" name="kg_security_flip_duration" />
+  <java-symbol type="layout" name="global_actions_item" />
+  <java-symbol type="layout" name="global_actions_silent_mode" />
+  <java-symbol type="layout" name="keyguard_screen_glogin_unlock" />
+  <java-symbol type="layout" name="keyguard_screen_password_landscape" />
+  <java-symbol type="layout" name="keyguard_screen_password_portrait" />
+  <java-symbol type="layout" name="keyguard_screen_sim_pin_landscape" />
+  <java-symbol type="layout" name="keyguard_screen_sim_pin_portrait" />
+  <java-symbol type="layout" name="keyguard_screen_sim_puk_landscape" />
+  <java-symbol type="layout" name="keyguard_screen_sim_puk_portrait" />
+  <java-symbol type="layout" name="keyguard_screen_tab_unlock" />
+  <java-symbol type="layout" name="keyguard_screen_tab_unlock_land" />
+  <java-symbol type="layout" name="keyguard_screen_unlock_landscape" />
+  <java-symbol type="layout" name="keyguard_screen_unlock_portrait" />
+  <java-symbol type="layout" name="keyguard_selector_view" />
+  <java-symbol type="layout" name="keyguard_pattern_view" />
+  <java-symbol type="layout" name="keyguard_password_view" />
+  <java-symbol type="layout" name="keyguard_face_unlock_view" />
+  <java-symbol type="layout" name="keyguard_sim_pin_view" />
+  <java-symbol type="layout" name="keyguard_sim_puk_view" />
+  <java-symbol type="layout" name="keyguard_account_view" />
+  <java-symbol type="layout" name="recent_apps_dialog" />
+  <java-symbol type="layout" name="screen_action_bar" />
+  <java-symbol type="layout" name="screen_action_bar_overlay" />
+  <java-symbol type="layout" name="screen_custom_title" />
+  <java-symbol type="layout" name="screen_progress" />
+  <java-symbol type="layout" name="screen_simple" />
+  <java-symbol type="layout" name="screen_simple_overlay_action_mode" />
+  <java-symbol type="layout" name="screen_title" />
+  <java-symbol type="layout" name="screen_title_icons" />
+  <java-symbol type="layout" name="keyguard_host_view" />
+  <java-symbol type="string" name="abbrev_wday_month_day_no_year" />
+  <java-symbol type="string" name="android_upgrading_title" />
+  <java-symbol type="string" name="bugreport_title" />
+  <java-symbol type="string" name="bugreport_message" />
+  <java-symbol type="string" name="faceunlock_multiple_failures" />
+  <java-symbol type="string" name="global_action_power_off" />
+  <java-symbol type="string" name="global_actions_airplane_mode_off_status" />
+  <java-symbol type="string" name="global_actions_airplane_mode_on_status" />
+  <java-symbol type="string" name="global_actions_toggle_airplane_mode" />
+  <java-symbol type="string" name="global_action_bug_report" />
+  <java-symbol type="string" name="global_action_silent_mode_off_status" />
+  <java-symbol type="string" name="global_action_silent_mode_on_status" />
+  <java-symbol type="string" name="global_action_toggle_silent_mode" />
+  <java-symbol type="string" name="invalidPuk" />
+  <java-symbol type="string" name="keyguard_password_enter_pin_code" />
+  <java-symbol type="string" name="keyguard_password_enter_puk_code" />
+  <java-symbol type="string" name="keyguard_password_wrong_pin_code" />
+  <java-symbol type="string" name="lockscreen_carrier_default" />
+  <java-symbol type="string" name="lockscreen_charged" />
+  <java-symbol type="string" name="lockscreen_failed_attempts_almost_at_wipe" />
+  <java-symbol type="string" name="lockscreen_failed_attempts_almost_glogin" />
+  <java-symbol type="string" name="lockscreen_failed_attempts_now_wiping" />
+  <java-symbol type="string" name="lockscreen_forgot_pattern_button_text" />
+  <java-symbol type="string" name="lockscreen_glogin_checking_password" />
+  <java-symbol type="string" name="lockscreen_glogin_forgot_pattern" />
+  <java-symbol type="string" name="lockscreen_glogin_invalid_input" />
+  <java-symbol type="string" name="lockscreen_glogin_too_many_attempts" />
+  <java-symbol type="string" name="lockscreen_instructions_when_pattern_disabled" />
+  <java-symbol type="string" name="lockscreen_low_battery" />
+  <java-symbol type="string" name="lockscreen_missing_sim_instructions" />
+  <java-symbol type="string" name="lockscreen_missing_sim_instructions_long" />
+  <java-symbol type="string" name="lockscreen_missing_sim_message_short" />
+  <java-symbol type="string" name="lockscreen_network_locked_message" />
+  <java-symbol type="string" name="lockscreen_password_wrong" />
+  <java-symbol type="string" name="lockscreen_pattern_instructions" />
+  <java-symbol type="string" name="lockscreen_pattern_wrong" />
+  <java-symbol type="string" name="lockscreen_permanent_disabled_sim_message_short" />
+  <java-symbol type="string" name="lockscreen_permanent_disabled_sim_instructions" />
+  <java-symbol type="string" name="lockscreen_plugged_in" />
+  <java-symbol type="string" name="lockscreen_sim_locked_message" />
+  <java-symbol type="string" name="lockscreen_sim_puk_locked_message" />
+  <java-symbol type="string" name="lockscreen_sim_unlock_progress_dialog_message" />
+  <java-symbol type="string" name="lockscreen_sound_off_label" />
+  <java-symbol type="string" name="lockscreen_sound_on_label" />
+  <java-symbol type="string" name="lockscreen_too_many_failed_attempts_countdown" />
+  <java-symbol type="string" name="lockscreen_too_many_failed_attempts_dialog_message" />
+  <java-symbol type="string" name="lockscreen_too_many_failed_password_attempts_dialog_message" />
+  <java-symbol type="string" name="lockscreen_too_many_failed_pin_attempts_dialog_message" />
+  <java-symbol type="string" name="lockscreen_unlock_label" />
+  <java-symbol type="string" name="status_bar_device_locked" />
+  <java-symbol type="style" name="Animation.LockScreen" />
+  <java-symbol type="style" name="Theme.Dialog.RecentApplications" />
+  <java-symbol type="style" name="Theme.ExpandedMenu" />
+  <java-symbol type="string" name="kg_emergency_call_label" />
+  <java-symbol type="string" name="kg_forgot_pattern_button_text" />
+  <java-symbol type="string" name="kg_wrong_pattern" />
+  <java-symbol type="string" name="kg_wrong_password" />
+  <java-symbol type="string" name="kg_wrong_pin" />
+  <java-symbol type="string" name="kg_too_many_failed_attempts_countdown" />
+  <java-symbol type="string" name="kg_pattern_instructions" />
+  <java-symbol type="string" name="kg_sim_pin_instructions" />
+  <java-symbol type="string" name="kg_pin_instructions" />
+  <java-symbol type="string" name="kg_password_instructions" />
+  <java-symbol type="string" name="kg_puk_enter_puk_hint" />
+  <java-symbol type="string" name="kg_puk_enter_pin_hint" />
+  <java-symbol type="string" name="kg_sim_unlock_progress_dialog_message" />
+  <java-symbol type="string" name="kg_password_wrong_pin_code" />
+  <java-symbol type="string" name="kg_invalid_sim_pin_hint" />
+  <java-symbol type="string" name="kg_invalid_sim_puk_hint" />
+  <java-symbol type="string" name="kg_sim_puk_recovery_hint" />
+  <java-symbol type="string" name="kg_invalid_puk" />
+  <java-symbol type="string" name="kg_login_too_many_attempts" />
+  <java-symbol type="string" name="kg_login_instructions" />
+  <java-symbol type="string" name="kg_login_username_hint" />
+  <java-symbol type="string" name="kg_login_password_hint" />
+  <java-symbol type="string" name="kg_login_submit_button" />
+  <java-symbol type="string" name="kg_login_invalid_input" />
+  <java-symbol type="string" name="kg_login_account_recovery_hint" />
+  <java-symbol type="string" name="kg_login_checking_password" />
+  <java-symbol type="string" name="kg_too_many_failed_pin_attempts_dialog_message" />
+  <java-symbol type="string" name="kg_too_many_failed_pattern_attempts_dialog_message" />
+  <java-symbol type="string" name="kg_too_many_failed_password_attempts_dialog_message" />
+  <java-symbol type="string" name="kg_failed_attempts_almost_at_wipe" />
+  <java-symbol type="string" name="kg_failed_attempts_now_wiping" />
+  <java-symbol type="string" name="kg_failed_attempts_almost_at_login" />
+
+  <!-- From services -->
+  <java-symbol type="anim" name="screen_rotate_0_enter" />
+  <java-symbol type="anim" name="screen_rotate_0_exit" />
+  <java-symbol type="anim" name="screen_rotate_0_frame" />
+  <java-symbol type="anim" name="screen_rotate_180_enter" />
+  <java-symbol type="anim" name="screen_rotate_180_exit" />
+  <java-symbol type="anim" name="screen_rotate_180_frame" />
+  <java-symbol type="anim" name="screen_rotate_finish_enter" />
+  <java-symbol type="anim" name="screen_rotate_finish_exit" />
+  <java-symbol type="anim" name="screen_rotate_finish_frame" />
+  <java-symbol type="anim" name="screen_rotate_minus_90_enter" />
+  <java-symbol type="anim" name="screen_rotate_minus_90_exit" />
+  <java-symbol type="anim" name="screen_rotate_minus_90_frame" />
+  <java-symbol type="anim" name="screen_rotate_plus_90_enter" />
+  <java-symbol type="anim" name="screen_rotate_plus_90_exit" />
+  <java-symbol type="anim" name="screen_rotate_plus_90_frame" />
+  <java-symbol type="anim" name="screen_rotate_start_enter" />
+  <java-symbol type="anim" name="screen_rotate_start_exit" />
+  <java-symbol type="anim" name="screen_rotate_start_frame" />
+  <java-symbol type="anim" name="screen_user_exit" />
+  <java-symbol type="anim" name="screen_user_enter" />
+  <java-symbol type="anim" name="window_move_from_decor" />
+  <java-symbol type="array" name="config_autoBrightnessButtonBacklightValues" />
+  <java-symbol type="array" name="config_autoBrightnessKeyboardBacklightValues" />
+  <java-symbol type="array" name="config_autoBrightnessLcdBacklightValues" />
+  <java-symbol type="array" name="config_autoBrightnessLevels" />
+  <java-symbol type="array" name="config_protectedNetworks" />
+  <java-symbol type="array" name="config_statusBarIcons" />
+  <java-symbol type="array" name="config_tether_bluetooth_regexs" />
+  <java-symbol type="array" name="config_tether_dhcp_range" />
+  <java-symbol type="array" name="config_tether_upstream_types" />
+  <java-symbol type="array" name="config_tether_usb_regexs" />
+  <java-symbol type="array" name="config_tether_wifi_regexs" />
+  <java-symbol type="array" name="config_usbHostBlacklist" />
+  <java-symbol type="array" name="config_serialPorts" />
+  <java-symbol type="array" name="radioAttributes" />
+  <java-symbol type="array" name="config_oemUsbModeOverride" />
+  <java-symbol type="array" name="config_locationProviderPackageNames" />
+  <java-symbol type="array" name="config_overlay_locationProviderPackageNames" />
+  <java-symbol type="bool" name="config_animateScreenLights" />
+  <java-symbol type="bool" name="config_automatic_brightness_available" />
+  <java-symbol type="bool" name="config_sf_limitedAlpha" />
+  <java-symbol type="bool" name="config_unplugTurnsOnScreen" />
+  <java-symbol type="bool" name="config_wifi_background_scan_support" />
+  <java-symbol type="bool" name="config_wifi_dual_band_support" />
+  <java-symbol type="bool" name="config_wimaxEnabled" />
+  <java-symbol type="bool" name="show_ongoing_ime_switcher" />
+  <java-symbol type="color" name="config_defaultNotificationColor" />
+  <java-symbol type="drawable" name="ic_notification_ime_default" />
+  <java-symbol type="drawable" name="stat_notify_car_mode" />
+  <java-symbol type="drawable" name="stat_notify_disabled" />
+  <java-symbol type="drawable" name="stat_notify_disk_full" />
+  <java-symbol type="drawable" name="stat_sys_adb" />
+  <java-symbol type="drawable" name="stat_sys_battery" />
+  <java-symbol type="drawable" name="stat_sys_battery_charge" />
+  <java-symbol type="drawable" name="stat_sys_battery_unknown" />
+  <java-symbol type="drawable" name="stat_sys_data_usb" />
+  <java-symbol type="drawable" name="stat_sys_tether_bluetooth" />
+  <java-symbol type="drawable" name="stat_sys_tether_general" />
+  <java-symbol type="drawable" name="stat_sys_tether_usb" />
+  <java-symbol type="drawable" name="stat_sys_throttled" />
+  <java-symbol type="drawable" name="vpn_connected" />
+  <java-symbol type="drawable" name="vpn_disconnected" />
+  <java-symbol type="id" name="ask_checkbox" />
+  <java-symbol type="id" name="compat_checkbox" />
+  <java-symbol type="id" name="original_app_icon" />
+  <java-symbol type="id" name="original_message" />
+  <java-symbol type="id" name="radio" />
+  <java-symbol type="id" name="reask_hint" />
+  <java-symbol type="id" name="replace_app_icon" />
+  <java-symbol type="id" name="replace_message" />
+  <java-symbol type="fraction" name="config_dimBehindFadeDuration" />
+  <java-symbol type="integer" name="config_carDockKeepsScreenOn" />
+  <java-symbol type="integer" name="config_criticalBatteryWarningLevel" />
+  <java-symbol type="integer" name="config_datause_notification_type" />
+  <java-symbol type="integer" name="config_datause_polling_period_sec" />
+  <java-symbol type="integer" name="config_datause_threshold_bytes" />
+  <java-symbol type="integer" name="config_datause_throttle_kbitsps" />
+  <java-symbol type="integer" name="config_defaultNotificationLedOff" />
+  <java-symbol type="integer" name="config_defaultNotificationLedOn" />
+  <java-symbol type="integer" name="config_deskDockKeepsScreenOn" />
+  <java-symbol type="integer" name="config_lightSensorWarmupTime" />
+  <java-symbol type="integer" name="config_lowBatteryCloseWarningLevel" />
+  <java-symbol type="integer" name="config_lowBatteryWarningLevel" />
+  <java-symbol type="integer" name="config_networkPolicyDefaultWarning" />
+  <java-symbol type="integer" name="config_networkTransitionTimeout" />
+  <java-symbol type="integer" name="config_notificationsBatteryFullARGB" />
+  <java-symbol type="integer" name="config_notificationsBatteryLedOff" />
+  <java-symbol type="integer" name="config_notificationsBatteryLedOn" />
+  <java-symbol type="integer" name="config_notificationsBatteryLowARGB" />
+  <java-symbol type="integer" name="config_notificationsBatteryMediumARGB" />
+  <java-symbol type="integer" name="config_radioScanningTimeout" />
+  <java-symbol type="integer" name="config_screenBrightnessSettingMinimum" />
+  <java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
+  <java-symbol type="integer" name="config_screenBrightnessSettingDefault" />
+  <java-symbol type="integer" name="config_screenBrightnessDim" />
+  <java-symbol type="integer" name="config_shutdownBatteryTemperature" />
+  <java-symbol type="integer" name="config_virtualKeyQuietTimeMillis" />
+  <java-symbol type="layout" name="am_compat_mode_dialog" />
+  <java-symbol type="layout" name="launch_warning" />
+  <java-symbol type="layout" name="safe_mode" />
+  <java-symbol type="layout" name="simple_list_item_2_single_choice" />
+  <java-symbol type="plurals" name="wifi_available" />
+  <java-symbol type="plurals" name="wifi_available_detailed" />
+  <java-symbol type="string" name="accessibility_binding_label" />
+  <java-symbol type="string" name="adb_active_notification_message" />
+  <java-symbol type="string" name="adb_active_notification_title" />
+  <java-symbol type="string" name="aerr_application" />
+  <java-symbol type="string" name="aerr_process" />
+  <java-symbol type="string" name="aerr_title" />
+  <java-symbol type="string" name="android_upgrading_apk" />
+  <java-symbol type="string" name="android_upgrading_complete" />
+  <java-symbol type="string" name="android_upgrading_starting_apps" />
+  <java-symbol type="string" name="anr_activity_application" />
+  <java-symbol type="string" name="anr_activity_process" />
+  <java-symbol type="string" name="anr_application_process" />
+  <java-symbol type="string" name="anr_process" />
+  <java-symbol type="string" name="anr_title" />
+  <java-symbol type="string" name="car_mode_disable_notification_message" />
+  <java-symbol type="string" name="car_mode_disable_notification_title" />
+  <java-symbol type="string" name="chooser_wallpaper" />
+  <java-symbol type="string" name="config_datause_iface" />
+  <java-symbol type="string" name="config_wimaxManagerClassname" />
+  <java-symbol type="string" name="config_wimaxNativeLibLocation" />
+  <java-symbol type="string" name="config_wimaxServiceClassname" />
+  <java-symbol type="string" name="config_wimaxServiceJarLocation" />
+  <java-symbol type="string" name="config_wimaxStateTrackerClassname" />
+  <java-symbol type="string" name="configure_input_methods" />
+  <java-symbol type="string" name="data_usage_3g_limit_snoozed_title" />
+  <java-symbol type="string" name="data_usage_3g_limit_title" />
+  <java-symbol type="string" name="data_usage_4g_limit_snoozed_title" />
+  <java-symbol type="string" name="data_usage_4g_limit_title" />
+  <java-symbol type="string" name="data_usage_limit_body" />
+  <java-symbol type="string" name="data_usage_limit_snoozed_body" />
+  <java-symbol type="string" name="data_usage_mobile_limit_snoozed_title" />
+  <java-symbol type="string" name="data_usage_mobile_limit_title" />
+  <java-symbol type="string" name="data_usage_restricted_body" />
+  <java-symbol type="string" name="data_usage_restricted_title" />
+  <java-symbol type="string" name="data_usage_warning_body" />
+  <java-symbol type="string" name="data_usage_warning_title" />
+  <java-symbol type="string" name="data_usage_wifi_limit_snoozed_title" />
+  <java-symbol type="string" name="data_usage_wifi_limit_title" />
+  <java-symbol type="string" name="default_wallpaper_component" />
+  <java-symbol type="string" name="dlg_ok" />
+  <java-symbol type="string" name="factorytest_failed" />
+  <java-symbol type="string" name="factorytest_no_action" />
+  <java-symbol type="string" name="factorytest_not_system" />
+  <java-symbol type="string" name="factorytest_reboot" />
+  <java-symbol type="string" name="hardware" />
+  <java-symbol type="string" name="heavy_weight_notification" />
+  <java-symbol type="string" name="heavy_weight_notification_detail" />
+  <java-symbol type="string" name="input_method_binding_label" />
+  <java-symbol type="string" name="launch_warning_original" />
+  <java-symbol type="string" name="launch_warning_replace" />
+  <java-symbol type="string" name="launch_warning_title" />
+  <java-symbol type="string" name="low_internal_storage_view_text" />
+  <java-symbol type="string" name="low_internal_storage_view_title" />
+  <java-symbol type="string" name="report" />
+  <java-symbol type="string" name="select_input_method" />
+  <java-symbol type="string" name="select_keyboard_layout_notification_title" />
+  <java-symbol type="string" name="select_keyboard_layout_notification_message" />
+  <java-symbol type="string" name="smv_application" />
+  <java-symbol type="string" name="smv_process" />
+  <java-symbol type="string" name="tethered_notification_message" />
+  <java-symbol type="string" name="tethered_notification_title" />
+  <java-symbol type="string" name="throttle_warning_notification_message" />
+  <java-symbol type="string" name="throttle_warning_notification_title" />
+  <java-symbol type="string" name="throttled_notification_message" />
+  <java-symbol type="string" name="throttled_notification_title" />
+  <java-symbol type="string" name="usb_accessory_notification_title" />
+  <java-symbol type="string" name="usb_cd_installer_notification_title" />
+  <java-symbol type="string" name="usb_mtp_notification_title" />
+  <java-symbol type="string" name="usb_notification_message" />
+  <java-symbol type="string" name="use_physical_keyboard" />
+  <java-symbol type="string" name="usb_ptp_notification_title" />
+  <java-symbol type="string" name="vpn_text" />
+  <java-symbol type="string" name="vpn_text_long" />
+  <java-symbol type="string" name="vpn_title" />
+  <java-symbol type="string" name="vpn_title_long" />
+  <java-symbol type="string" name="vpn_lockdown_connecting" />
+  <java-symbol type="string" name="vpn_lockdown_connected" />
+  <java-symbol type="string" name="vpn_lockdown_error" />
+  <java-symbol type="string" name="vpn_lockdown_reset" />
+  <java-symbol type="string" name="wallpaper_binding_label" />
+  <java-symbol type="style" name="Theme.Dialog.AppError" />
+  <java-symbol type="style" name="Theme.Toast" />
+  <java-symbol type="xml" name="storage_list" />
+  <java-symbol type="bool" name="config_enableDreams" />
+  <java-symbol type="string" name="enable_explore_by_touch_warning_title" />
+  <java-symbol type="string" name="enable_explore_by_touch_warning_message" />
+
+  <java-symbol type="layout" name="resolver_grid" />
+  <java-symbol type="id" name="resolver_grid" />
+  <java-symbol type="id" name="button_once" />
+  <java-symbol type="id" name="button_always" />
+  <java-symbol type="integer" name="config_maxResolverActivityColumns" />
+
+  <!-- From SystemUI -->
+  <java-symbol type="anim" name="push_down_in" />
+  <java-symbol type="anim" name="push_down_out" />
+  <java-symbol type="anim" name="push_up_in" />
+  <java-symbol type="anim" name="push_up_out" />
+  <java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
+  <java-symbol type="dimen" name="status_bar_icon_size" />
+  <java-symbol type="dimen" name="system_bar_icon_size" />
+  <java-symbol type="drawable" name="list_selector_pressed_holo_dark" />
+  <java-symbol type="drawable" name="scrubber_control_disabled_holo" />
+  <java-symbol type="drawable" name="scrubber_control_selector_holo" />
+  <java-symbol type="drawable" name="scrubber_progress_horizontal_holo_dark" />
+  <java-symbol type="drawable" name="usb_android" />
+  <java-symbol type="drawable" name="usb_android_connected" />
+  <java-symbol type="id" name="banner" />
+  <java-symbol type="id" name="mount_button" />
+  <java-symbol type="id" name="unmount_button" />
+  <java-symbol type="layout" name="usb_storage_activity" />
+  <java-symbol type="string" name="chooseUsbActivity" />
+  <java-symbol type="string" name="dlg_confirm_kill_storage_users_text" />
+  <java-symbol type="string" name="dlg_confirm_kill_storage_users_title" />
+  <java-symbol type="string" name="dlg_error_title" />
+  <java-symbol type="string" name="ext_media_badremoval_notification_message" />
+  <java-symbol type="string" name="ext_media_badremoval_notification_title" />
+  <java-symbol type="string" name="ext_media_checking_notification_message" />
+  <java-symbol type="string" name="ext_media_checking_notification_title" />
+  <java-symbol type="string" name="ext_media_nofs_notification_message" />
+  <java-symbol type="string" name="ext_media_nofs_notification_title" />
+  <java-symbol type="string" name="ext_media_nomedia_notification_message" />
+  <java-symbol type="string" name="ext_media_nomedia_notification_title" />
+  <java-symbol type="string" name="ext_media_safe_unmount_notification_message" />
+  <java-symbol type="string" name="ext_media_safe_unmount_notification_title" />
+  <java-symbol type="string" name="ext_media_unmountable_notification_message" />
+  <java-symbol type="string" name="ext_media_unmountable_notification_title" />
+  <java-symbol type="string" name="usb_storage_error_message" />
+  <java-symbol type="string" name="usb_storage_message" />
+  <java-symbol type="string" name="usb_storage_notification_message" />
+  <java-symbol type="string" name="usb_storage_notification_title" />
+  <java-symbol type="string" name="usb_storage_stop_message" />
+  <java-symbol type="string" name="usb_storage_stop_notification_message" />
+  <java-symbol type="string" name="usb_storage_stop_notification_title" />
+  <java-symbol type="string" name="usb_storage_stop_title" />
+  <java-symbol type="string" name="usb_storage_title" />
+  <java-symbol type="style" name="Animation.RecentApplications" />
+
+  <!-- ImfTest -->
+  <java-symbol type="layout" name="auto_complete_list" />
+
+  <!-- From SettingsProvider -->
+  <java-symbol type="raw" name="fallbackring" />
+
+  <!-- From Settings -->
+  <java-symbol type="array" name="config_mobile_hotspot_provision_app" />
+  <java-symbol type="bool" name="config_intrusiveNotificationLed" />
+  <java-symbol type="dimen" name="preference_fragment_padding_bottom" />
+  <java-symbol type="dimen" name="preference_fragment_padding_side" />
+  <java-symbol type="drawable" name="expander_ic_maximized" />
+  <java-symbol type="drawable" name="expander_ic_minimized" />
+  <java-symbol type="drawable" name="ic_menu_archive" />
+  <java-symbol type="drawable" name="ic_menu_goto" />
+  <java-symbol type="drawable" name="ic_settings_language" />
+  <java-symbol type="drawable" name="title_bar_medium" />
+  <java-symbol type="id" name="body" />
+  <java-symbol type="string" name="fast_scroll_alphabet" />
+  <java-symbol type="string" name="ssl_certificate" />
+
+  <!-- From Phone -->
+  <java-symbol type="bool" name="config_built_in_sip_phone" />
+
+  <!-- From TelephonyProvider -->
+  <java-symbol type="xml" name="apns" />
+
+  <!-- From ContactsProvider -->
+  <java-symbol type="array" name="common_nicknames" />
+  <java-symbol type="drawable" name="call_contact" />
+  <java-symbol type="drawable" name="create_contact" />
+  <java-symbol type="string" name="common_name_prefixes" />
+  <java-symbol type="string" name="common_last_name_prefixes" />
+  <java-symbol type="string" name="common_name_suffixes" />
+  <java-symbol type="string" name="common_name_conjunctions" />
+  <java-symbol type="string" name="dial_number_using" />
+  <java-symbol type="string" name="create_contact_using" />
+
+  <!-- From DownloadProvider -->
+  <java-symbol type="integer" name="config_MaxConcurrentDownloadsAllowed" />
+  <java-symbol type="integer" name="config_downloadDataDirSize" />
+  <java-symbol type="integer" name="config_downloadDataDirLowSpaceThreshold" />
+
+  <!-- From Contacts -->
+  <java-symbol type="drawable" name="quickcontact_badge_overlay_dark" />
+
+  <!-- From Browser -->
+  <java-symbol type="drawable" name="ic_menu_moreoverflow_normal_holo_dark" />
+  <java-symbol type="id" name="placeholder" />
+  <java-symbol type="string" name="ssl_certificate_is_valid" />
+
+  <!-- From Mms -->
+  <java-symbol type="drawable" name="ic_menu_play_clip" />
+
+  <!-- From Stk -->
+  <java-symbol type="bool" name="config_sf_slowBlur" />
+  <java-symbol type="drawable" name="ic_volume" />
+  <java-symbol type="drawable" name="stat_notify_sim_toolkit" />
+
+  <!-- From maps library -->
+  <java-symbol type="array" name="maps_starting_lat_lng" />
+  <java-symbol type="array" name="maps_starting_zoom" />
+  <java-symbol type="attr" name="mapViewStyle" />
+  <java-symbol type="attr" name="state_focused" />
+  <java-symbol type="attr" name="state_selected" />
+  <java-symbol type="attr" name="state_pressed" />
+  <java-symbol type="drawable" name="compass_arrow" />
+  <java-symbol type="drawable" name="compass_base" />
+  <java-symbol type="drawable" name="ic_maps_indicator_current_position_anim" />
+  <java-symbol type="drawable" name="loading_tile_android" />
+  <java-symbol type="drawable" name="maps_google_logo" />
+  <java-symbol type="drawable" name="no_tile_256" />
+  <java-symbol type="drawable" name="reticle" />
+
+  <!-- From PinyinIME(!!!) -->
+  <java-symbol type="string" name="inputMethod" />
+
+</resources>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 216344d..561e33e 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -36,6 +36,7 @@
 import android.os.PowerManager;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -696,12 +697,12 @@
      */
     public void setAirplaneMode(Context context, boolean enableAM) {
         //set the airplane mode
-        Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
+        Settings.Global.putInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
                 enableAM ? 1 : 0);
         // Post the intent
         Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         intent.putExtra("state", enableAM);
-        context.sendBroadcast(intent);
+        context.sendBroadcastAsUser(intent, UserHandle.ALL);
     }
 
     protected static String convertToQuotedString(String string) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index bf188d3..7928822 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -59,8 +59,8 @@
         wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "CMWakeLock");
         wl.acquire();
         // Each test case will start with cellular connection
-        if (Settings.System.getInt(getInstrumentation().getContext().getContentResolver(),
-                Settings.System.AIRPLANE_MODE_ON) == 1) {
+        if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON) == 1) {
             log("airplane is not disabled, disable it.");
             cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
         }
@@ -84,8 +84,8 @@
         wl.release();
         cmActivity.removeConfiguredNetworksAndDisableWifi();
         // if airplane mode is set, disable it.
-        if (Settings.System.getInt(getInstrumentation().getContext().getContentResolver(),
-                Settings.System.AIRPLANE_MODE_ON) == 1) {
+        if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON) == 1) {
             log("disable airplane mode if it is enabled");
             cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
         }
diff --git a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
index b2075ae..af2a944 100644
--- a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
+++ b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
@@ -29,6 +29,7 @@
 import android.net.wifi.WifiManager;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
 import android.os.ParcelFileDescriptor.AutoCloseInputStream;
 import android.os.SystemClock;
 import android.provider.Settings;
@@ -553,7 +554,7 @@
         int state = enable ? 1 : 0;
 
         // Change the system setting
-        Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
                 state);
 
         String timeoutMessage = "Timed out waiting for airplane mode to be " +
@@ -561,8 +562,8 @@
 
         // wait for airplane mode to change state
         int currentWaitTime = 0;
-        while (Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.AIRPLANE_MODE_ON, -1) != state) {
+        while (Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON, -1) != state) {
             timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME, DEFAULT_MAX_WAIT_TIME,
                     timeoutMessage);
         }
@@ -570,7 +571,7 @@
         // Post the intent
         Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         intent.putExtra("state", true);
-        mContext.sendBroadcast(intent);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
     }
 
     /**
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 1868d1c..785842f 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -72,6 +72,8 @@
 
     public final long WAIT_TIME_INCR = 5 * 1000;
 
+    private static final String APP_LIB_DIR_PREFIX = "/data/app-lib/";
+
     private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec/";
 
     private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO;
@@ -433,7 +435,7 @@
                     assertEquals(srcPath, appInstallPath);
                     assertEquals(publicSrcPath, appInstallPath);
                     assertStartsWith("Native library should point to shared lib directory",
-                            dataDir.getPath(),
+                            new File(APP_LIB_DIR_PREFIX, info.packageName).getPath(),
                             info.nativeLibraryDir);
                     assertDirOwnerGroupPerms(
                             "Native library directory should be owned by system:system and 0755",
diff --git a/docs/html/guide/google/play/publishing/multiple-apks.jd b/docs/html/guide/google/play/publishing/multiple-apks.jd
index e41817e..0619dfc 100644
--- a/docs/html/guide/google/play/publishing/multiple-apks.jd
+++ b/docs/html/guide/google/play/publishing/multiple-apks.jd
@@ -9,9 +9,7 @@
   <ul>
     <li>Simultaneously publish different APKs for different
 device configurations</li>
-    <li>Different APKs are distributed to different devices based on filters declared in the
-manifest file</li>
-    <li>You should publish multiple APKs only when it's not possible or reasonable to
+    <li>You should publish multiple APKs only when it's not possible to
 support all desired devices with a single APK</li>
   </ul>
 
@@ -39,16 +37,17 @@
       <li><a href="#TextureOptions">Supporting multiple GL textures</a></li>
       <li><a href="#ScreenOptions">Supporting multiple screens</a></li>
       <li><a href="#ApiLevelOptions">Supporting multiple API levels</a></li>
+      <li><a href="#CpuArchOptions">Supporting multiple CPU architectures</a></li>
     </ol>
   </li>
 </ol>
 
   <h2>See also</h2>
 <ol>
+  <li><a href="{@docRoot}guide/google/play/expansion-files.html">APK Expansion Files</a></li>
   <li><a href="{@docRoot}guide/google/play/filters.html">Filters on Google Play</a></li>
   <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
-  <li><a href="{@docRoot}tools/extras/support-library.html">Compatibility
-Package</a></li>
+  <li><a href="{@docRoot}tools/extras/support-library.html">Support Library</a></li>
   <li><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">Android API Levels</a></li>
 </ol>
 
@@ -76,14 +75,16 @@
 you publish your application for as many devices as possible, Google Play allows you to
 publish multiple APKs under the same application listing. Google Play then supplies each APK to
 the appropriate devices based on configuration support you've declared in the manifest file of each
-APK.</p>
+APK. </p>
 
 <p>By publishing your application with multiple APKs, you can:</p>
 
 <ul>
   <li>Support different OpenGL texture compression formats with each APK.</li>
-  <li>Support different screen configurations with each APK.</li>
+  <li>Support different screen sizes and densities with each APK.</li>
   <li>Support different platform versions with each APK.</li>
+  <li>Support different CPU architectures with each APK (such as for ARM, x86, and MIPS, when your
+  app uses the <a href="{@docRoot}tools/sdk/ndk/index.html">Android NDK</a>).</li>
 </ul>
 
 <p>Currently, these are the only device characteristics that Google Play supports for publishing
@@ -91,7 +92,8 @@
 
 <p class="note"><strong>Note:</strong> You should generally use multiple APKs to support
 different device configurations <strong>only when your APK is too large</strong> (greater than
-50MB). Using a single APK to support different configurations is always the best practice,
+50MB) due to the alternative resources needed for different device configurations.
+Using a single APK to support different configurations is always the best practice,
 because it makes the path for application updates simple and clear for users (and also makes
 your life simpler by avoiding development and publishing complexity). Read the section below about
 <a href="#SingleAPK">Using a Single APK Instead</a> to
@@ -283,14 +285,19 @@
     </ul>
   </div>
   </li>
+
+  <li><strong>CPU architecture (ABI)</strong>
+    <p>This is based on the native libraries included in each APK (which are
+    determined by the architectures you declare in the {@code Application.mk}
+    file) when using the Android NDK.</p></li>
 </ul>
 
 <p>Other manifest elements that enable <a
 href="{@docRoot}guide/google/play/filters.html">Google Play filters</a>&mdash;but are not
 listed above&mdash;are still applied for each APK as usual. However, Google Play does not allow
-you to publish multiple APKs based on variations of them. Thus, you cannot publish
-multiple APKs if the above listed filters are the same for each APK (but the APKs differ based on
-other characteristics in the manifest file). For
+you to publish separate APKs based on variations of those device characteristics. Thus, you cannot
+publish multiple APKs if the above listed filters are the same for each APK (but the APKs differ
+based on other characteristics in the manifest or APK). For
 example, you cannot provide different APKs that differ purely on the <a
 href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">{@code
 &lt;uses-configuration&gt;}</a> characteristics.</p>
@@ -349,7 +356,8 @@
 get an update when they receive a system update.</li>
       <li>If you have one APK that's for API level 4 (and above) <em>and</em> small -
 large screens, and another APK for API level 8 (and above) <em>and</em> large - xlarge screens, then
-the version codes <strong>must increase</strong>. In this case, the API level filter is used to
+the version codes <strong>must increase</strong> in correlation with the API levels.
+In this case, the API level filter is used to
 distinguish each APK, but so is the screen size. Because the screen sizes overlap (both APKs
 support large screens), the version codes must still be in order. This ensures that a large screen
 device that receives a system update to API level 8 will receive an update for the second
@@ -360,6 +368,21 @@
 levels. Because there is no overlap within the screen size filter, there are no devices that
 could potentially move between these two APKs, so there's no need for the version codes to
 increase from the lower API level to the higher API level.</li>
+      <li>If you have one APK that's for API level 4 (and above) <em>and</em> ARMv7 CPUs,
+and another APK for API level 8 (and above) <em>and</em> ARMv5TE CPUs,
+then the version codes <strong>must increase</strong> in correlation with the API levels.
+In this case, the API level filter is used to
+distinguish each APK, but so is the CPU architecture. Because an APK with ARMv5TE libraries is
+compatible with devices that have an ARMv7 CPU, the APKs overlap on this characteristic.
+As such, the version code for the APK that supports API level 8 and above must be higher.
+This ensures that a device with an ARMv7 CPU that receives a system update to API level 8
+will receive an update for the second APK that's designed for API level 8.
+However, because this kind of update results in the ARMv7 device using an APK that's not
+fully optimized for that device's CPU, you should provide an
+APK for both the ARMv5TE and the ARMv7 architecture at each API level in order to optimize
+the app performance on each CPU.
+<strong>Note:</strong> This applies <em>only</em> when comparing APKs with the ARMv5TE and
+ARMv7 libraries, and not when comparing other native libraries.</li>
     </ul>
   </li>
 
@@ -384,7 +407,12 @@
 sizes small, normal, and large, while another APK supports sizes large and xlarge, there is an
 overlap, because both APKs support large screens. If you do not resolve this, then devices that
 qualify for both APKs (large screen devices in the example) will receive whichever APK has the
-highest version code.</li>
+highest version code.
+  <p class="note"><strong>Note:</strong> If you're creating separate APKs for different CPU
+  architectures, be aware that an APK for ARMv5TE will overlap with an APK for ARMv7. That is,
+  an APK designed for ARMv5TE is compatible with an ARMv7 device,
+but the reverse is not true (an APK with only the ARMv7 libraries is
+<em>not</em> compatible with an ARMv5TE device).</li>
 </ul>
 
 <p>When such conflicts occur, you will see a warning message, but you can still publish your
@@ -641,3 +669,17 @@
 }
 </pre>
 
+
+<h3 id="CpuArchOptions">Supporting multiple CPU architectures</h3>
+
+<p>When using the Android NDK, you can create a single APK that supports multiple CPU architectures
+by declaring each of the desired architectures with the {@code APP_ABI} variable in the
+<code>Application.mk</code> file.</p>
+
+<p>For example, here's an <code>Application.mk</code> file that declares support for three
+different CPU architectures:</p>
+
+<pre>
+APP_ABI := armeabi armeabi-v7a mips
+APP_PLATFORM := android-9
+</pre>
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index b2c95b9..749e458 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -573,6 +573,10 @@
           no display</li>
         </ul>
         <p><em>Added in API level 8, television added in API 13.</em></p>
+        <p>For information about how your app can respond when the device is inserted into or
+        removed from a dock, read <a 
+        href="{@docRoot}training/monitoring-device-state/docking-monitoring.html">Determining
+and Monitoring the Docking State and Type</a>.</p>
         <p>This can change during the life of your application if the user places the device in a
 dock. You can enable or disable some of these modes using {@link
 android.app.UiModeManager}. See <a href="runtime-changes.html">Handling Runtime Changes</a> for
diff --git a/docs/html/guide/topics/ui/themes.jd b/docs/html/guide/topics/ui/themes.jd
index d787492..bc1c4f0 100644
--- a/docs/html/guide/topics/ui/themes.jd
+++ b/docs/html/guide/topics/ui/themes.jd
@@ -413,8 +413,8 @@
 themes will give you a better understanding of what style properties each one provides.
 For a better reference to the Android styles and themes, see the following source code:</p>
 <ul>
-	<li><a href="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/res/res/values/styles.xml;h=d7b654e49809cb97a35682754b1394af5c8bc88b;hb=HEAD">Android Styles (styles.xml)</a></li>
-	<li><a href="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/res/res/values/themes.xml;h=6b3d7407d1c895a3c297e60d5beac98e2d34c271;hb=HEAD">Android Themes (themes.xml)</a></li>
+	<li><a href="https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/res/res/values/styles.xml">Android Styles (styles.xml)</a></li>
+	<li><a href="https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/res/res/values/themes.xml">Android Themes (themes.xml)</a></li>
 </ul>
 
 <p>These files will help you learn through example. For instance, in the Android themes source code,
@@ -422,9 +422,8 @@
 you'll see all of the properties that are used to style dialogs that are used by the Android
 framework.</p>
 
-<p>For more information about the syntax used to create styles in XML, see
-<a href="{@docRoot}guide/topics/resources/available-resources.html#stylesandthemes">Available Resource Types:
-Style and Themes</a>.</p>
+<p>For more information about the syntax for styles and themes in XML, see the
+<a href="{@docRoot}guide/topics/resources/style-resource.html">Style Resource</a> document.</p>
 
 <p>For a reference of available style attributes that you can use to define a style or theme
 (e.g., "windowBackground" or "textAppearance"), see {@link android.R.attr} or the respective
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 4fc2ca6..feec56df 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -63,23 +63,20 @@
 
 <h2 id="Configure">Configure the ADT Plugin</h2>
 
-<p>After you've installed ADT and restarted Eclipse, you
+<p>Once Eclipse restarts, you
   must specify the location of your Android SDK directory:</p>
 
 <ol>
-    <li>Select <strong>Window</strong> &gt; <strong>Preferences...</strong> to open the Preferences
-        panel (on Mac OS X, select <strong>Eclipse</strong> &gt; <strong>Preferences</strong>).</li>
-    <li>Select <strong>Android</strong> from the left panel.</li>
-      <p>You may see a dialog asking whether you want to send usage statistics to Google. If so,
-make your choice and click <strong>Proceed</strong>.</p>
-    <li>For the <em>SDK Location</em> in the main panel, click <strong>Browse...</strong> and
-        locate your downloaded Android SDK directory (such as <code>android-sdk-windows</code>).</li>
-    <li>Click <strong>Apply</strong>, then <strong>OK</strong>.</li>
+    <li>In the "Welcome to Android Development" window that appears, select <strong>Use
+existing SDKs</strong>.</li>
+    <li>Browse and select the location of the Android SDK directory you recently
+downloaded.</li>
+    <li>Click <strong>Next</strong>.</li>
 </ol>
 
 
 <p>If you haven't encountered any errors, you're done setting up ADT
-  and can continue to the next step of the SDK installation.</p>
+  and can continue to <a href="{@docRoot}sdk/installing/next.html">Next Steps</a>.</p>
 
 
 
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
new file mode 100644
index 0000000..56c5426
--- /dev/null
+++ b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -0,0 +1,66 @@
+/*
+ * 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.renderscript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+/**
+ * @hide
+ **/
+public class ScriptIntrinsicBlur extends ScriptIntrinsic {
+    private float[] mValues = new float[9];
+    private Allocation mInput;
+
+    ScriptIntrinsicBlur(int id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Supported elements types are float, float4, uchar, uchar4
+     *
+     *
+     * @param rs
+     * @param e
+     *
+     * @return ScriptIntrinsicConvolve3x3
+     */
+    public static ScriptIntrinsicBlur create(RenderScript rs, Element e) {
+        int id = rs.nScriptIntrinsicCreate(5, e.getID(rs));
+        return new ScriptIntrinsicBlur(id, rs);
+
+    }
+
+    public void setInput(Allocation ain) {
+        mInput = ain;
+        bindAllocation(ain, 1);
+    }
+
+    public void setRadius(float v) {
+        if (v < 0 || v > 25) {
+            throw new RSIllegalArgumentException("Radius out of range (0-25).");
+        }
+        setVar(0, v);
+    }
+
+    public void forEach(Allocation aout) {
+        forEach(0, null, aout, null);
+    }
+
+}
+
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
new file mode 100644
index 0000000..242623b
--- /dev/null
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -0,0 +1,66 @@
+/*
+ * 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.renderscript;
+
+import android.util.Log;
+
+/**
+ * @hide
+ **/
+public class ScriptIntrinsicConvolve5x5 extends ScriptIntrinsic {
+    private float[] mValues = new float[25];
+    private Allocation mInput;
+
+    ScriptIntrinsicConvolve5x5(int id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Supported elements types are float, float4, uchar, uchar4
+     *
+     *
+     * @param rs
+     * @param e
+     *
+     * @return ScriptIntrinsicConvolve5x5
+     */
+    public static ScriptIntrinsicConvolve5x5 create(RenderScript rs, Element e) {
+        int id = rs.nScriptIntrinsicCreate(4, e.getID(rs));
+        return new ScriptIntrinsicConvolve5x5(id, rs);
+
+    }
+
+    public void setInput(Allocation ain) {
+        mInput = ain;
+        bindAllocation(ain, 1);
+    }
+
+    public void setCoefficients(float v[]) {
+        FieldPacker fp = new FieldPacker(25*4);
+        for (int ct=0; ct < mValues.length; ct++) {
+            mValues[ct] = v[ct];
+            fp.addF32(mValues[ct]);
+        }
+        setVar(0, fp);
+    }
+
+    public void forEach(Allocation aout) {
+        forEach(0, null, aout, null);
+    }
+
+}
+
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
new file mode 100644
index 0000000..e7d8d34
--- /dev/null
+++ b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
@@ -0,0 +1,110 @@
+/*
+ * 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.renderscript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+
+/**
+ * @hide
+ **/
+public class ScriptIntrinsicLUT extends ScriptIntrinsic {
+    private Matrix4f mMatrix = new Matrix4f();
+    private Allocation mTables;
+    private byte mCache[] = new byte[1024];
+    private boolean mDirty = true;
+
+    ScriptIntrinsicLUT(int id, RenderScript rs) {
+        super(id, rs);
+        mTables = Allocation.createSized(rs, Element.U8(rs), 1024);
+        for (int ct=0; ct < 256; ct++) {
+            mCache[ct] = (byte)ct;
+            mCache[ct + 256] = (byte)ct;
+            mCache[ct + 512] = (byte)ct;
+            mCache[ct + 768] = (byte)ct;
+        }
+        bindAllocation(mTables, 0);
+    }
+
+    /**
+     * Supported elements types are uchar4
+     *
+     * @param rs
+     * @param e
+     *
+     * @return ScriptIntrinsicColorMatrix
+     */
+    public static ScriptIntrinsicLUT create(RenderScript rs, Element e) {
+        int id = rs.nScriptIntrinsicCreate(3, e.getID(rs));
+        return new ScriptIntrinsicLUT(id, rs);
+
+    }
+
+
+    private void validate(int index, int value) {
+        if (index < 0 || index > 255) {
+            throw new RSIllegalArgumentException("Index out of range (0-255).");
+        }
+        if (value < 0 || value > 255) {
+            throw new RSIllegalArgumentException("Value out of range (0-255).");
+        }
+    }
+
+    public void setRed(int index, int value) {
+        validate(index, value);
+        mCache[index] = (byte)value;
+        mDirty = true;
+    }
+
+    public void setGreen(int index, int value) {
+        validate(index, value);
+        mCache[index+256] = (byte)value;
+        mDirty = true;
+    }
+
+    public void setBlue(int index, int value) {
+        validate(index, value);
+        mCache[index+512] = (byte)value;
+        mDirty = true;
+    }
+
+    public void setAlpha(int index, int value) {
+        validate(index, value);
+        mCache[index+768] = (byte)value;
+        mDirty = true;
+    }
+
+
+    /**
+     * Invoke the kernel and apply the matrix to each cell of ain and copy to
+     * aout.
+     *
+     * @param ain Input allocation
+     * @param aout Output allocation
+     */
+    public void forEach(Allocation ain, Allocation aout) {
+        if (mDirty) {
+            mDirty = false;
+            mTables.copyFromUnchecked(mCache);
+        }
+        forEach(0, ain, aout, null);
+    }
+
+}
+
diff --git a/include/androidfw/Input.h b/include/androidfw/Input.h
index 2c91fab..e88835e 100644
--- a/include/androidfw/Input.h
+++ b/include/androidfw/Input.h
@@ -49,6 +49,15 @@
 };
 
 enum {
+    /* Used when a motion event is not associated with any display.
+     * Typically used for non-pointer events. */
+    ADISPLAY_ID_NONE = -1,
+
+    /* The default display id. */
+    ADISPLAY_ID_DEFAULT = 0,
+};
+
+enum {
     /*
      * Indicates that an input device has switches.
      * This input source flag is hidden from the API because switches are only used by the system
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index b233ff6..d8109ce 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -20,8 +20,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.util.Log;
-import com.android.org.bouncycastle.openssl.PEMReader;
-import com.android.org.bouncycastle.openssl.PEMWriter;
+import com.android.org.bouncycastle.util.io.pem.PemObject;
+import com.android.org.bouncycastle.util.io.pem.PemReader;
+import com.android.org.bouncycastle.util.io.pem.PemWriter;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -32,6 +33,10 @@
 import java.io.Writer;
 import java.nio.charset.Charsets;
 import java.security.KeyPair;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.List;
@@ -108,34 +113,41 @@
     public static final String EXTRA_CA_CERTIFICATES_DATA = "ca_certificates_data";
 
     /**
-     * Convert objects to a PEM format, which is used for
-     * CA_CERTIFICATE, USER_CERTIFICATE, and USER_PRIVATE_KEY
-     * entries.
+     * Convert objects to a PEM format which is used for
+     * CA_CERTIFICATE and USER_CERTIFICATE entries.
      */
-    public static byte[] convertToPem(Object... objects) throws IOException {
+    public static byte[] convertToPem(Certificate... objects)
+            throws IOException, CertificateEncodingException {
         ByteArrayOutputStream bao = new ByteArrayOutputStream();
         Writer writer = new OutputStreamWriter(bao, Charsets.US_ASCII);
-        PEMWriter pw = new PEMWriter(writer);
-        for (Object o : objects) {
-            pw.writeObject(o);
+        PemWriter pw = new PemWriter(writer);
+        for (Certificate o : objects) {
+            pw.writeObject(new PemObject("CERTIFICATE", o.getEncoded()));
         }
         pw.close();
         return bao.toByteArray();
     }
     /**
      * Convert objects from PEM format, which is used for
-     * CA_CERTIFICATE, USER_CERTIFICATE, and USER_PRIVATE_KEY
-     * entries.
+     * CA_CERTIFICATE and USER_CERTIFICATE entries.
      */
-    public static List<Object> convertFromPem(byte[] bytes) throws IOException {
+    public static List<X509Certificate> convertFromPem(byte[] bytes)
+            throws IOException, CertificateException {
         ByteArrayInputStream bai = new ByteArrayInputStream(bytes);
         Reader reader = new InputStreamReader(bai, Charsets.US_ASCII);
-        PEMReader pr = new PEMReader(reader);
+        PemReader pr = new PemReader(reader);
 
-        List<Object> result = new ArrayList<Object>();
-        Object o;
-        while ((o = pr.readObject()) != null) {
-            result.add(o);
+        CertificateFactory cf = CertificateFactory.getInstance("X509");
+
+        List<X509Certificate> result = new ArrayList<X509Certificate>();
+        PemObject o;
+        while ((o = pr.readPemObject()) != null) {
+            if (o.getType().equals("CERTIFICATE")) {
+                Certificate c = cf.generateCertificate(new ByteArrayInputStream(o.getContent()));
+                result.add((X509Certificate) c);
+            } else {
+                throw new IllegalArgumentException("Unknown type " + o.getType());
+            }
         }
         pr.close();
         return result;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 755170f..c3444e6 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -1412,8 +1412,12 @@
     mSnapshot = new Snapshot(mFirstSnapshot,
             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     mSaveCount = 1;
+
     mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
+    mDirtyClip = opaque;
+
     mRestoreSaveCount = -1;
+
     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
 }
 
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 5a8f2b7..02af5e2 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -332,10 +332,10 @@
         if (Caches::getInstance().extensions.hasDiscardFramebuffer()) {
             GLuint previousFbo;
             glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
-
-            GLenum attachments = GL_COLOR_ATTACHMENT0;
             if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-            glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachments);
+
+            const GLenum attachments[] = { GL_COLOR_ATTACHMENT0 };
+            glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, attachments);
 
             if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
         }
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index f4c2675..02448e8 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -173,6 +173,15 @@
     mSnapshot->setClip(left, top, right, bottom);
     mDirtyClip = opaque;
 
+    // If we know that we are going to redraw the entire framebuffer,
+    // perform a discard to let the driver know we don't need to preserve
+    // the back buffer for this frame.
+    if (mCaches.extensions.hasDiscardFramebuffer() &&
+            left <= 0.0f && top <= 0.0f && right >= mWidth && bottom >= mHeight) {
+        const GLenum attachments[] = { getTargetFbo() == 0 ? GL_COLOR_EXT : GL_COLOR_ATTACHMENT0 };
+        glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, attachments);
+    }
+
     syncState();
 
     if (!opaque) {
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 6971d8a..abc88fa 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -266,6 +266,11 @@
     const uint32_t oldQuadCount = quadCount;
     quadCount++;
 
+    if (x1 < 0.0f) x1 = 0.0f;
+    if (x2 < 0.0f) x2 = 0.0f;
+    if (y1 < 0.0f) y1 = 0.0f;
+    if (y2 < 0.0f) y2 = 0.0f;
+
     // Skip degenerate and transparent (empty) quads
     if ((mColorKey >> oldQuadCount) & 0x1) {
 #if DEBUG_PATCHES_EMPTY_VERTICES
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index b5613f3..ea00ec8 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1164,7 +1164,7 @@
     /**
      * Indicates if current platform supports use of SCO for off call use cases.
      * Application wanted to use bluetooth SCO audio when the phone is not in call
-     * must first call thsi method to make sure that the platform supports this
+     * must first call this method to make sure that the platform supports this
      * feature.
      * @return true if bluetooth SCO can be used for audio when not in call
      *         false otherwise
@@ -1300,6 +1300,19 @@
     }
 
     /**
+     * @hide
+     * Signals whether remote submix audio rerouting is enabled.
+     */
+    public void setRemoteSubmixOn(boolean on, int address) {
+        IAudioService service = getService();
+        try {
+            service.setRemoteSubmixOn(on, address);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Dead object in setRemoteSubmixOn", e);
+        }
+    }
+
+    /**
      * Sets audio routing to the wired headset on or off.
      *
      * @param on set <var>true</var> to route audio to/from wired
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index aea8a88..e5c2a4d 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -151,6 +151,8 @@
     private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 21;
     private static final int MSG_SET_A2DP_CONNECTION_STATE = 22;
     // end of messages handled under wakelock
+    private static final int MSG_SET_RSX_CONNECTION_STATE = 23; // change remote submix connection
+    private static final int MSG_SET_FORCE_RSX_USE = 24;        // force remote submix audio routing
 
     // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
     // persisted
@@ -2109,6 +2111,33 @@
         }
     };
 
+    /** see AudioManager.setRemoteSubmixOn(boolean on) */
+    public void setRemoteSubmixOn(boolean on, int address) {
+        sendMsg(mAudioHandler, MSG_SET_RSX_CONNECTION_STATE,
+                SENDMSG_REPLACE /* replace with QUEUE when multiple addresses are supported */,
+                on ? 1 : 0 /*arg1*/,
+                address /*arg2*/,
+                null/*obj*/, 0/*delay*/);
+
+        // Note that we are  currently forcing use of remote submix as soon as corresponding device
+        //   is made available
+        sendMsg(mAudioHandler, MSG_SET_FORCE_RSX_USE, SENDMSG_REPLACE,
+                AudioSystem.FOR_MEDIA,
+                on ? AudioSystem.FORCE_REMOTE_SUBMIX : AudioSystem.FORCE_NONE,
+                null/*obj*/, 0/*delay*/);
+    }
+
+    private void onSetRsxConnectionState(int available, int address) {
+        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_REMOTE_SUBMIX,
+                available == 1 ?
+                        AudioSystem.DEVICE_STATE_AVAILABLE : AudioSystem.DEVICE_STATE_UNAVAILABLE,
+                String.valueOf(address) /*device_address*/);
+        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX,
+                available == 1 ?
+                        AudioSystem.DEVICE_STATE_AVAILABLE : AudioSystem.DEVICE_STATE_UNAVAILABLE,
+                String.valueOf(address) /*device_address*/);
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // Internal methods
     ///////////////////////////////////////////////////////////////////////////
@@ -3072,6 +3101,7 @@
 
                 case MSG_SET_FORCE_USE:
                 case MSG_SET_FORCE_BT_A2DP_USE:
+                case MSG_SET_FORCE_RSX_USE:
                     setForceUse(msg.arg1, msg.arg2);
                     break;
 
@@ -3134,6 +3164,10 @@
                     onRegisterVolumeObserverForRcc(msg.arg1 /* rccId */,
                             (IRemoteVolumeObserver)msg.obj /* rvo */);
                     break;
+
+                case MSG_SET_RSX_CONNECTION_STATE:
+                    onSetRsxConnectionState(msg.arg1/*available*/, msg.arg2/*address*/);
+                    break;
             }
         }
     }
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index f3a8558..129e84f 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -214,6 +214,7 @@
     public static final int DEVICE_OUT_REMOTE_SUBMIX = 0x8000;
 
     public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT;
+
     public static final int DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE |
                                               DEVICE_OUT_SPEAKER |
                                               DEVICE_OUT_WIRED_HEADSET |
@@ -352,7 +353,8 @@
     public static final int FORCE_ANALOG_DOCK = 8;
     public static final int FORCE_DIGITAL_DOCK = 9;
     public static final int FORCE_NO_BT_A2DP = 10;
-    private static final int NUM_FORCE_CONFIG = 11;
+    public static final int FORCE_REMOTE_SUBMIX = 11;
+    private static final int NUM_FORCE_CONFIG = 12;
     public static final int FORCE_DEFAULT = FORCE_NONE;
 
     // usage for setForceUse, must match AudioSystem::force_use
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 854eb3f..7ae61cd 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -108,6 +108,8 @@
 
     boolean isBluetoothA2dpOn();
 
+    oneway void setRemoteSubmixOn(boolean on, int address);
+
     int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb, IAudioFocusDispatcher l,
             String clientId, String callingPackageName);
 
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 2d1be02..48bea52 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -177,6 +177,12 @@
          *  is applied.
          */
         public static final int VOICE_COMMUNICATION = 7;
+
+        /**
+         * @hide
+         * Audio source for remote submix.
+         */
+        public static final int REMOTE_SUBMIX_SOURCE = 8;
     }
 
     /**
@@ -291,7 +297,12 @@
      * Gets the maximum value for audio sources.
      * @see android.media.MediaRecorder.AudioSource
      */
-    public static final int getAudioSourceMax() { return AudioSource.VOICE_COMMUNICATION; }
+    public static final int getAudioSourceMax() {
+        // FIXME disable selection of the remote submxi source selection once test code
+        //       doesn't rely on it
+        return AudioSource.REMOTE_SUBMIX_SOURCE;
+        //return AudioSource.VOICE_COMMUNICATION;
+    }
 
     /**
      * Sets the video source to be used for recording. If this method is not
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 7532d79..79250fb 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -103,8 +103,8 @@
     private static final String PATH_WHERE = Files.FileColumns.DATA + "=?";
 
     private static final String STORAGE_WHERE = Files.FileColumns.STORAGE_ID + "=?";
-    private static final String FORMAT_WHERE = Files.FileColumns.PARENT + "=?";
-    private static final String PARENT_WHERE = Files.FileColumns.FORMAT + "=?";
+    private static final String FORMAT_WHERE = Files.FileColumns.FORMAT + "=?";
+    private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?";
     private static final String STORAGE_FORMAT_WHERE = STORAGE_WHERE + " AND "
                                             + Files.FileColumns.FORMAT + "=?";
     private static final String STORAGE_PARENT_WHERE = STORAGE_WHERE + " AND "
diff --git a/media/tests/EffectsTest/res/layout/bassboosttest.xml b/media/tests/EffectsTest/res/layout/bassboosttest.xml
index 0888e98..ac912c8 100755
--- a/media/tests/EffectsTest/res/layout/bassboosttest.xml
+++ b/media/tests/EffectsTest/res/layout/bassboosttest.xml
@@ -105,6 +105,8 @@
             style="@android:style/TextAppearance.Medium" />
 
         <EditText android:id="@+id/sessionEdit"
+            android:singleLine="true"
+            android:numeric="integer"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_weight="0.5"
diff --git a/media/tests/EffectsTest/res/layout/equalizertest.xml b/media/tests/EffectsTest/res/layout/equalizertest.xml
index 2223c48..5ef035d 100755
--- a/media/tests/EffectsTest/res/layout/equalizertest.xml
+++ b/media/tests/EffectsTest/res/layout/equalizertest.xml
@@ -105,6 +105,8 @@
             style="@android:style/TextAppearance.Medium" />
 
         <EditText android:id="@+id/sessionEdit"
+            android:singleLine="true"
+            android:numeric="integer"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_weight="0.5"
diff --git a/media/tests/EffectsTest/res/layout/presetreverbtest.xml b/media/tests/EffectsTest/res/layout/presetreverbtest.xml
index b648899..cd7fbd3 100755
--- a/media/tests/EffectsTest/res/layout/presetreverbtest.xml
+++ b/media/tests/EffectsTest/res/layout/presetreverbtest.xml
@@ -105,6 +105,8 @@
             style="@android:style/TextAppearance.Medium" />
 
         <EditText android:id="@+id/sessionEdit"
+            android:singleLine="true"
+            android:numeric="integer"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_weight="0.5"
diff --git a/media/tests/EffectsTest/res/layout/virtualizertest.xml b/media/tests/EffectsTest/res/layout/virtualizertest.xml
index c9203de..1fafeab 100755
--- a/media/tests/EffectsTest/res/layout/virtualizertest.xml
+++ b/media/tests/EffectsTest/res/layout/virtualizertest.xml
@@ -105,6 +105,8 @@
             style="@android:style/TextAppearance.Medium" />
 
         <EditText android:id="@+id/sessionEdit"
+            android:singleLine="true"
+            android:numeric="integer"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_weight="0.5"
diff --git a/media/tests/EffectsTest/res/layout/visualizertest.xml b/media/tests/EffectsTest/res/layout/visualizertest.xml
index 8611e8c..50ac7bb 100755
--- a/media/tests/EffectsTest/res/layout/visualizertest.xml
+++ b/media/tests/EffectsTest/res/layout/visualizertest.xml
@@ -105,6 +105,8 @@
             style="@android:style/TextAppearance.Medium" />
 
         <EditText android:id="@+id/sessionEdit"
+            android:singleLine="true"
+            android:numeric="integer"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_weight="0.5"
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java b/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java
index 6612766..70202463 100755
--- a/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java
+++ b/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java
@@ -32,6 +32,7 @@
 import android.widget.BaseAdapter;
 import android.widget.LinearLayout;
 import android.media.audiofx.AudioEffect;
+
 import java.util.UUID;
 
 public class EffectsTest extends Activity {
@@ -154,13 +155,35 @@
             this.setOrientation(VERTICAL);
         }
 
+        public String effectUuidToString(UUID effectType) {
+            if (effectType.equals(AudioEffect.EFFECT_TYPE_VIRTUALIZER)) {
+                return "Virtualizer";
+            } else if (effectType.equals(AudioEffect.EFFECT_TYPE_ENV_REVERB)){
+                return "Reverb";
+            } else if (effectType.equals(AudioEffect.EFFECT_TYPE_PRESET_REVERB)){
+                return "Preset Reverb";
+            } else if (effectType.equals(AudioEffect.EFFECT_TYPE_EQUALIZER)){
+                return "Equalizer";
+            } else if (effectType.equals(AudioEffect.EFFECT_TYPE_BASS_BOOST)){
+                return "Bass Boost";
+            } else if (effectType.equals(AudioEffect.EFFECT_TYPE_AGC)){
+                return "Automatic Gain Control";
+            } else if (effectType.equals(AudioEffect.EFFECT_TYPE_AEC)){
+                return "Acoustic Echo Canceler";
+            } else if (effectType.equals(AudioEffect.EFFECT_TYPE_NS)){
+                return "Noise Suppressor";
+            }
+
+            return effectType.toString();
+        }
+
         public void set(int position) {
             TextView tv = new TextView(mContext);
             tv.setText("Effect "+ position);
             addView(tv, new LinearLayout.LayoutParams(
                     LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
             tv = new TextView(mContext);
-            tv.setText(" type: "+ mDescriptors[position].type.toString());
+            tv.setText(" type: "+ effectUuidToString(mDescriptors[position].type));
             addView(tv, new LinearLayout.LayoutParams(
                     LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
             tv = new TextView(mContext);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index f859f41..523b95e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -22,6 +22,7 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.backup.BackupManager;
 import android.content.BroadcastReceiver;
@@ -421,10 +422,6 @@
                     }
                 }
             }, userFilter);
-
-            if (!ensureAndroidIdIsSet()) {
-                return false;
-            }
         }
         return true;
     }
@@ -472,6 +469,8 @@
         sObserverInstances.append(userHandle, observer);
         observer.startWatching();
 
+        ensureAndroidIdIsSet(userHandle);
+
         startAsyncCachePopulation(userHandle);
     }
 
@@ -536,24 +535,27 @@
         }
     }
 
-    private boolean ensureAndroidIdIsSet() {
-        final Cursor c = query(Settings.Secure.CONTENT_URI,
+    private boolean ensureAndroidIdIsSet(int userHandle) {
+        final Cursor c = queryForUser(Settings.Secure.CONTENT_URI,
                 new String[] { Settings.NameValueTable.VALUE },
                 Settings.NameValueTable.NAME + "=?",
-                new String[] { Settings.Secure.ANDROID_ID }, null);
+                new String[] { Settings.Secure.ANDROID_ID }, null,
+                userHandle);
         try {
             final String value = c.moveToNext() ? c.getString(0) : null;
             if (value == null) {
                 final SecureRandom random = new SecureRandom();
                 final String newAndroidIdValue = Long.toHexString(random.nextLong());
-                Log.d(TAG, "Generated and saved new ANDROID_ID [" + newAndroidIdValue + "]");
                 final ContentValues values = new ContentValues();
                 values.put(Settings.NameValueTable.NAME, Settings.Secure.ANDROID_ID);
                 values.put(Settings.NameValueTable.VALUE, newAndroidIdValue);
-                final Uri uri = insert(Settings.Secure.CONTENT_URI, values);
+                final Uri uri = insertForUser(Settings.Secure.CONTENT_URI, values, userHandle);
                 if (uri == null) {
+                    Slog.e(TAG, "Unable to generate new ANDROID_ID for user " + userHandle);
                     return false;
                 }
+                Slog.d(TAG, "Generated and saved new ANDROID_ID [" + newAndroidIdValue
+                        + "] for user " + userHandle);
             }
             return true;
         } finally {
@@ -621,24 +623,10 @@
         if (args != null) {
             int reqUser = args.getInt(Settings.CALL_METHOD_USER_KEY, callingUser);
             if (reqUser != callingUser) {
-                getContext().enforceCallingPermission(
-                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                        "Not permitted to access settings for other users");
-                if (reqUser == UserHandle.USER_CURRENT) {
-                    try {
-                        reqUser = ActivityManagerNative.getDefault().getCurrentUser().id;
-                    } catch (RemoteException e) {
-                        // can't happen
-                    }
-                    if (LOCAL_LOGV) {
-                        Slog.v(TAG, "   USER_CURRENT resolved to " + reqUser);
-                    }
-                }
-                if (reqUser < 0) {
-                    throw new IllegalArgumentException("Bad user handle " + reqUser);
-                }
-                callingUser = reqUser;
-                if (LOCAL_LOGV) Slog.v(TAG, "   fetching setting for user " + callingUser);
+                callingUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+                        Binder.getCallingUid(), reqUser, false, true,
+                        "get/set setting for user", null);
+                if (LOCAL_LOGV) Slog.v(TAG, "   access setting for user " + callingUser);
             }
         }
 
@@ -678,9 +666,6 @@
         // the Settings.NameValueTable.VALUE static.
         final String newValue = (args == null)
                 ? null : args.getString(Settings.NameValueTable.VALUE);
-        if (newValue == null) {
-            throw new IllegalArgumentException("Bad value for " + method);
-        }
 
         final ContentValues values = new ContentValues();
         values.put(Settings.NameValueTable.NAME, request);
@@ -748,12 +733,17 @@
 
     @Override
     public Cursor query(Uri url, String[] select, String where, String[] whereArgs, String sort) {
-        final int callingUser = UserHandle.getCallingUserId();
-        if (LOCAL_LOGV) Slog.v(TAG, "query() for user " + callingUser);
+        return queryForUser(url, select, where, whereArgs, sort, UserHandle.getCallingUserId());
+    }
+
+    public Cursor queryForUser(Uri url, String[] select, String where, String[] whereArgs,
+            String sort, int forUser) {
+        if (LOCAL_LOGV) Slog.v(TAG, "query(" + url + ") for user " + forUser);
         SqlArguments args = new SqlArguments(url, where, whereArgs);
         DatabaseHelper dbH;
         synchronized (this) {
-            dbH = getOrEstablishDatabaseLocked(callingUser);
+            dbH = getOrEstablishDatabaseLocked(
+                    TABLE_GLOBAL.equals(args.table) ? UserHandle.USER_OWNER : forUser);
         }
         SQLiteDatabase db = dbH.getReadableDatabase();
 
@@ -811,7 +801,8 @@
         mutationCount.incrementAndGet();
         DatabaseHelper dbH;
         synchronized (this) {
-            dbH = getOrEstablishDatabaseLocked(callingUser);
+            dbH = getOrEstablishDatabaseLocked(
+                    TABLE_GLOBAL.equals(args.table) ? UserHandle.USER_OWNER : callingUser);
         }
         SQLiteDatabase db = dbH.getWritableDatabase();
         db.beginTransaction();
@@ -914,7 +905,7 @@
     private Uri insertForUser(Uri url, ContentValues initialValues, int desiredUserHandle) {
         final int callingUser = UserHandle.getCallingUserId();
         if (callingUser != desiredUserHandle) {
-            getContext().enforceCallingPermission(
+            getContext().enforceCallingOrSelfPermission(
                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                     "Not permitted to access settings for other users");
         }
@@ -950,7 +941,7 @@
         mutationCount.incrementAndGet();
         DatabaseHelper dbH;
         synchronized (this) {
-            dbH = getOrEstablishDatabaseLocked(callingUser);
+            dbH = getOrEstablishDatabaseLocked(desiredUserHandle);
         }
         SQLiteDatabase db = dbH.getWritableDatabase();
         final long rowId = db.insert(args.table, null, initialValues);
@@ -968,13 +959,15 @@
 
     @Override
     public int delete(Uri url, String where, String[] whereArgs) {
-        final int callingUser = UserHandle.getCallingUserId();
+        int callingUser = UserHandle.getCallingUserId();
         if (LOCAL_LOGV) Slog.v(TAG, "delete() for user " + callingUser);
         SqlArguments args = new SqlArguments(url, where, whereArgs);
         if (TABLE_FAVORITES.equals(args.table)) {
             return 0;
         } else if (TABLE_OLD_FAVORITES.equals(args.table)) {
             args.table = TABLE_FAVORITES;
+        } else if (TABLE_GLOBAL.equals(args.table)) {
+            callingUser = UserHandle.USER_OWNER;
         }
         checkWritePermissions(args);
 
@@ -1003,11 +996,13 @@
         // intended effect (the update will be invisible to the rest of the system).
         // This should have no practical effect, since writes to the Secure db can only
         // be done by system code, and that code should be using the correct API up front.
-        final int callingUser = UserHandle.getCallingUserId();
+        int callingUser = UserHandle.getCallingUserId();
         if (LOCAL_LOGV) Slog.v(TAG, "update() for user " + callingUser);
         SqlArguments args = new SqlArguments(url, where, whereArgs);
         if (TABLE_FAVORITES.equals(args.table)) {
             return 0;
+        } else if (TABLE_GLOBAL.equals(args.table)) {
+            callingUser = UserHandle.USER_OWNER;
         }
         checkWritePermissions(args);
 
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 22a97bd..44fb49a 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -19,6 +19,7 @@
     <uses-permission android:name="android.permission.READ_PROFILE" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
     <!-- Networking and telephony -->
     <uses-permission android:name="android.permission.BLUETOOTH" />
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
new file mode 100644
index 0000000..528121e
--- /dev/null
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+
+<LinearLayout 
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:padding="16dp">
+
+    <ImageView
+        android:id="@+id/brightness_icon"
+        style="@style/SystemBarPanelSettingsIcon"
+        android:src="@drawable/ic_sysbar_brightness"
+        />
+    <com.android.systemui.statusbar.policy.ToggleSlider
+        android:id="@+id/brightness_slider"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:layout_marginRight="2dp"
+        systemui:text="@string/status_bar_settings_auto_brightness_label"
+        />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_time.xml b/packages/SystemUI/res/layout/quick_settings_tile_time.xml
index ab0c52d..3d7b095 100644
--- a/packages/SystemUI/res/layout/quick_settings_tile_time.xml
+++ b/packages/SystemUI/res/layout/quick_settings_tile_time.xml
@@ -32,4 +32,12 @@
         android:layout_height="wrap_content"
         android:layout_gravity="center_horizontal"
         />
+    <TextView
+        android:textAppearance="@style/TextAppearance.QuickSettings.Alarm"
+        android:id="@+id/alarm_textview"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:drawableLeft="@drawable/stat_sys_alarm"
+        />
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 2bcf951..6aed1aa 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -155,13 +155,13 @@
     <string name="always_use_accessory">Use by default for this USB accessory</string>
 
     <!-- Title of confirmation dialog for USB debugging -->
-    <string name="usb_debugging_title">Allow USB Debugging?</string>
+    <string name="usb_debugging_title">Allow USB debugging?</string>
 
     <!-- Message of confirmation dialog for USB debugging -->
-    <string name="usb_debugging_message">Allow USB Debugging from this computer?\nYour RSA key fingerprint is\n<xliff:g id="fingerprint">%1$s</xliff:g></string>
+    <string name="usb_debugging_message">The computer\'s RSA key fingerprint is:\n<xliff:g id="fingerprint">%1$s</xliff:g></string>
 
     <!-- Option to always allow USB debugging from the attached computer -->
-    <string name="usb_debugging_always">Always allow this computer</string>
+    <string name="usb_debugging_always">Always allow from this computer</string>
 
     <!-- Checkbox label for application compatibility mode ON (zooming app to look like it's running
          on a phone).  [CHAR LIMIT=25] -->
@@ -433,6 +433,10 @@
     <string name="quick_settings_wifi_display_label">Wifi Display</string>
     <!-- QuickSettings: Wifi display [CHAR LIMIT=NONE] -->
     <string name="quick_settings_wifi_display_no_connection_label">No Wifi Display Connection</string>
+    <!-- QuickSettings: Brightness dialog title [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_brightness_dialog_title">Brightness</string>
+    <!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_brightness_dialog_auto_brightness_label">AUTO</string>
 
     <!-- Wifi display: Scan button text [CHAR LIMIT=15] -->
     <string name="wifi_display_scan">Scan</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 34bd627..fa62cb6 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -92,6 +92,11 @@
         <item name="android:textSize">14dp</item>
     </style>
 
+    <style name="TextAppearance.QuickSettings.Alarm" parent="@style/TextAppearance.QuickSettings.TileView">
+        <item name="android:textSize">13dp</item>
+        <item name="android:textColor">#ff3a3b39</item>
+    </style>
+
     <style name="Animation" />
 
     <style name="Animation.ShirtPocketPanel">
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index f374c11..1c3cb2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -17,11 +17,11 @@
 package com.android.systemui.statusbar.phone;
 
 import android.app.Dialog;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.CursorLoader;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.Loader;
@@ -32,11 +32,12 @@
 import android.hardware.display.WifiDisplay;
 import android.hardware.display.WifiDisplayStatus;
 import android.net.Uri;
+import android.os.UserHandle;
 import android.provider.ContactsContract;
-import android.provider.Settings;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
 import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
@@ -44,290 +45,18 @@
 import android.widget.ListView;
 import android.widget.TextView;
 
-import java.util.ArrayList;
-import java.util.Comparator;
-
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
 import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 import com.android.systemui.statusbar.policy.BluetoothController;
+import com.android.systemui.statusbar.policy.BrightnessController;
 import com.android.systemui.statusbar.policy.LocationController;
-import com.android.systemui.statusbar.policy.LocationController.LocationGpsStateChangeCallback;
 import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+import com.android.systemui.statusbar.policy.ToggleSlider;
 
-class QuickSettingsModel implements BluetoothStateChangeCallback,
-        NetworkSignalChangedCallback,
-        BatteryStateChangeCallback,
-        LocationGpsStateChangeCallback {
+import java.util.ArrayList;
+import java.util.Comparator;
 
-    /** Represents the state of a given attribute. */
-    static class State {
-        int iconId;
-        String label;
-        boolean enabled;
-    }
-    static class BatteryState extends State {
-        int batteryLevel;
-        boolean pluggedIn;
-    }
-
-    /** The callback to update a given tile. */
-    interface RefreshCallback {
-        public void refreshView(QuickSettingsTileView view, State state);
-    }
-
-    private Context mContext;
-
-    private QuickSettingsTileView mUserTile;
-    private RefreshCallback mUserCallback;
-    private State mUserState = new State();
-
-    private QuickSettingsTileView mAirplaneModeTile;
-    private RefreshCallback mAirplaneModeCallback;
-    private State mAirplaneModeState = new State();
-
-    private QuickSettingsTileView mWifiTile;
-    private RefreshCallback mWifiCallback;
-    private State mWifiState = new State();
-
-    private QuickSettingsTileView mWifiDisplayTile;
-    private RefreshCallback mWifiDisplayCallback;
-    private State mWifiDisplayState = new State();
-
-    private QuickSettingsTileView mRSSITile;
-    private RefreshCallback mRSSICallback;
-    private State mRSSIState = new State();
-
-    private QuickSettingsTileView mBluetoothTile;
-    private RefreshCallback mBluetoothCallback;
-    private State mBluetoothState = new State();
-
-    private QuickSettingsTileView mBatteryTile;
-    private RefreshCallback mBatteryCallback;
-    private BatteryState mBatteryState = new BatteryState();
-
-    private QuickSettingsTileView mLocationTile;
-    private RefreshCallback mLocationCallback;
-    private State mLocationState = new State();
-
-    public QuickSettingsModel(Context context) {
-        mContext = context;
-    }
-
-    // User
-    void addUserTile(QuickSettingsTileView view, RefreshCallback cb) {
-        mUserTile = view;
-        mUserCallback = cb;
-        mUserCallback.refreshView(mUserTile, mUserState);
-    }
-    void setUserTileInfo(String name) {
-        mUserState.label = name;
-        mUserCallback.refreshView(mUserTile, mUserState);
-    }
-
-    // Airplane Mode
-    void addAirplaneModeTile(QuickSettingsTileView view, RefreshCallback cb) {
-        mAirplaneModeTile = view;
-        mAirplaneModeTile.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (mAirplaneModeState.enabled) {
-                    setAirplaneModeState(false);
-                } else {
-                    setAirplaneModeState(true);
-                }
-            }
-        });
-        mAirplaneModeCallback = cb;
-        mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
-    }
-    private void setAirplaneModeState(boolean enabled) {
-        // TODO: Sets the view to be "awaiting" if not already awaiting
-
-        // Change the system setting
-        Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
-                                enabled ? 1 : 0);
-
-        // TODO: Update the UI to reflect system setting
-        // mCheckBoxPref.setChecked(enabled);
-
-        // Post the intent
-        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        intent.putExtra("state", enabled);
-        mContext.sendBroadcast(intent);
-    }
-    // NetworkSignalChanged callback
-    @Override
-    public void onAirplaneModeChanged(boolean enabled) {
-        // TODO: If view is in awaiting state, disable
-        Resources r = mContext.getResources();
-        mAirplaneModeState.enabled = enabled;
-        mAirplaneModeState.iconId = (enabled ?
-                R.drawable.ic_qs_airplane_enabled :
-                R.drawable.ic_qs_airplane_normal);
-        mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
-    }
-
-    // Wifi
-    void addWifiTile(QuickSettingsTileView view, RefreshCallback cb) {
-        mWifiTile = view;
-        mWifiCallback = cb;
-        mWifiCallback.refreshView(mWifiTile, mWifiState);
-    }
-    // NetworkSignalChanged callback
-    @Override
-    public void onWifiSignalChanged(boolean enabled, String description) {
-        // TODO: If view is in awaiting state, disable
-        Resources r = mContext.getResources();
-        // TODO: Check if wifi is enabled
-        mWifiState.enabled = enabled;
-        mWifiState.iconId = (enabled ?
-                R.drawable.ic_qs_wifi_enabled :
-                R.drawable.ic_qs_wifi_normal);
-        mWifiState.label = (enabled ?
-                description :
-                r.getString(R.string.quick_settings_wifi_no_network));
-        mWifiCallback.refreshView(mWifiTile, mWifiState);
-    }
-
-    // RSSI
-    void addRSSITile(QuickSettingsTileView view, RefreshCallback cb) {
-        mRSSITile = view;
-        mRSSICallback = cb;
-        mRSSICallback.refreshView(mRSSITile, mRSSIState);
-    }
-    private void setRSSIState(boolean enabled) {
-        // TODO: Set RSSI enabled
-        // TODO: Sets the view to be "awaiting" if not already awaiting
-    }
-    // NetworkSignalChanged callback
-    @Override
-    public void onMobileDataSignalChanged(boolean enabled, String description) {
-        // TODO: If view is in awaiting state, disable
-        Resources r = mContext.getResources();
-        // TODO: Check if RSSI is enabled
-        mRSSIState.enabled = enabled;
-        mRSSIState.iconId = (enabled ?
-                R.drawable.ic_qs_rssi_enabled :
-                R.drawable.ic_qs_rssi_normal);
-        mRSSIState.label = (enabled ?
-                description :
-                r.getString(R.string.quick_settings_rssi_emergency_only));
-        mRSSICallback.refreshView(mRSSITile, mRSSIState);
-    }
-
-    // Bluetooth
-    void addBluetoothTile(QuickSettingsTileView view, RefreshCallback cb) {
-        mBluetoothTile = view;
-        mBluetoothTile.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (mBluetoothState.enabled) {
-                    setBluetoothState(false);
-                } else {
-                    setBluetoothState(true);
-                }
-            }
-        });
-        mBluetoothCallback = cb;
-
-        final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        onBluetoothStateChange(adapter.isEnabled());
-    }
-    private void setBluetoothState(boolean enabled) {
-        // TODO: Sets the view to be "awaiting" if not already awaiting
-        final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        if (adapter != null) {
-            if (enabled) {
-                adapter.enable();
-            } else {
-                adapter.disable();
-            }
-        }
-    }
-    // BluetoothController callback
-    @Override
-    public void onBluetoothStateChange(boolean on) {
-        // TODO: If view is in awaiting state, disable
-        Resources r = mContext.getResources();
-        mBluetoothState.enabled = on;
-        if (on) {
-            mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_enabled;
-        } else {
-            mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_normal;
-        }
-        mBluetoothCallback.refreshView(mBluetoothTile, mBluetoothState);
-    }
-
-    // Battery
-    void addBatteryTile(QuickSettingsTileView view, RefreshCallback cb) {
-        mBatteryTile = view;
-        mBatteryCallback = cb;
-        mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
-    }
-    // BatteryController callback
-    @Override
-    public void onBatteryLevelChanged(int level, boolean pluggedIn) {
-        mBatteryState.batteryLevel = level;
-        mBatteryState.pluggedIn = pluggedIn;
-        mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
-    }
-
-    // Location
-    void addLocationTile(QuickSettingsTileView view, RefreshCallback cb) {
-        mLocationTile = view;
-        mLocationCallback = cb;
-        mLocationCallback.refreshView(mLocationTile, mLocationState);
-        disableLocationTile();
-    }
-    private void enableLocationTile() {
-        mLocationTile.setVisibility(View.VISIBLE);
-    }
-    private void disableLocationTile() {
-        mLocationTile.setVisibility(View.GONE);
-    }
-    // LocationController callback
-    @Override
-    public void onLocationGpsStateChanged(boolean inUse, String description) {
-        if (inUse) {
-            mLocationState.enabled = inUse;
-            mLocationState.label = description;
-            mLocationCallback.refreshView(mLocationTile, mLocationState);
-            enableLocationTile();
-        } else {
-            disableLocationTile();
-        }
-    }
-
-    // Wifi Display
-    void addWifiDisplayTile(QuickSettingsTileView view, RefreshCallback cb) {
-        mWifiDisplayTile = view;
-        mWifiDisplayCallback = cb;
-    }
-    private void enableWifiDisplayTile() {
-        mWifiDisplayTile.setVisibility(View.VISIBLE);
-    }
-    private void disableWifiDisplayTile() {
-        mWifiDisplayTile.setVisibility(View.GONE);
-    }
-    public void onWifiDisplayStateChanged(WifiDisplayStatus status) {
-        if (status.isEnabled()) {
-            if (status.getActiveDisplay() != null) {
-                mWifiDisplayState.label = status.getActiveDisplay().getDeviceName();
-            } else {
-                mWifiDisplayState.label = mContext.getString(
-                        R.string.quick_settings_wifi_display_no_connection_label);
-            }
-            mWifiDisplayCallback.refreshView(mWifiDisplayTile, mWifiDisplayState);
-            enableWifiDisplayTile();
-        } else {
-            disableWifiDisplayTile();
-        }
-    }
-
-}
 
 /**
  *
@@ -342,6 +71,9 @@
     private DisplayManager mDisplayManager;
     private WifiDisplayStatus mWifiDisplayStatus;
     private WifiDisplayListAdapter mWifiDisplayListAdapter;
+    
+    private BrightnessController mBrightnessController;
+    private Dialog mBrightnessDialog;
 
     private CursorLoader mUserInfoLoader;
 
@@ -430,6 +162,16 @@
         queryForUserInformation();
     }
 
+    private void startSettingsActivity(String action) {
+        Intent intent = new Intent(action);
+        startSettingsActivity(intent);
+    }
+    private void startSettingsActivity(Intent intent) {
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        mBar.collapseAllPanels(true);
+        mContext.startActivity(intent);
+    }
+
     private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
         QuickSettingsTileView userTile = (QuickSettingsTileView)
                 inflater.inflate(R.layout.quick_settings_tile, parent, false);
@@ -448,6 +190,25 @@
         QuickSettingsTileView timeTile = (QuickSettingsTileView)
                 inflater.inflate(R.layout.quick_settings_tile, parent, false);
         timeTile.setContent(R.layout.quick_settings_tile_time, inflater);
+        timeTile.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                // TODO: Jump into the alarm application
+                Intent intent = new Intent();
+                intent.setComponent(new ComponentName(
+                        "com.google.android.deskclock",
+                        "com.android.deskclock.AlarmClock"));
+                startSettingsActivity(intent);
+            }
+        });
+        mModel.addTimeTile(timeTile, new QuickSettingsModel.RefreshCallback() {
+            @Override
+            public void refreshView(QuickSettingsTileView view, State alarmState) {
+                TextView tv = (TextView) view.findViewById(R.id.alarm_textview);
+                tv.setText(alarmState.label);
+                tv.setVisibility(alarmState.enabled ? View.VISIBLE : View.GONE);
+            }
+        });
         parent.addView(timeTile);
         mDynamicSpannedTiles.add(timeTile);
 
@@ -458,10 +219,7 @@
         settingsTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
-                mBar.collapseAllPanels(true);
+                startSettingsActivity(android.provider.Settings.ACTION_SETTINGS);
             }
         });
         parent.addView(settingsTile);
@@ -476,10 +234,7 @@
         wifiTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                Intent intent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
-                mBar.collapseAllPanels(true);
+                startSettingsActivity(android.provider.Settings.ACTION_WIFI_SETTINGS);
             }
         });
         mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
@@ -499,10 +254,11 @@
         rssiTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
-                mBar.collapseAllPanels(true);
+                Intent intent = new Intent();
+                intent.setComponent(new ComponentName(
+                        "com.android.settings",
+                        "com.android.settings.Settings$DataUsageSummaryActivity"));
+                startSettingsActivity(intent);
             }
         });
         mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
@@ -522,10 +278,7 @@
         batteryTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
-                mBar.collapseAllPanels(true);
+                startSettingsActivity(Intent.ACTION_POWER_USAGE_SUMMARY);
             }
         });
         mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() {
@@ -556,17 +309,25 @@
         parent.addView(airplaneTile);
 
         // Bluetooth
-        QuickSettingsTileView bluetoothTile = (QuickSettingsTileView)
-                inflater.inflate(R.layout.quick_settings_tile, parent, false);
-        bluetoothTile.setContent(R.layout.quick_settings_tile_bluetooth, inflater);
-        mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
-            @Override
-            public void refreshView(QuickSettingsTileView view, State state) {
-                TextView tv = (TextView) view.findViewById(R.id.bluetooth_textview);
-                tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
-            }
-        });
-        parent.addView(bluetoothTile);
+        if (mModel.deviceSupportsBluetooth()) {
+            QuickSettingsTileView bluetoothTile = (QuickSettingsTileView)
+                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
+            bluetoothTile.setContent(R.layout.quick_settings_tile_bluetooth, inflater);
+            bluetoothTile.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    startSettingsActivity(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
+                }
+            });
+            mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
+                @Override
+                public void refreshView(QuickSettingsTileView view, State state) {
+                    TextView tv = (TextView) view.findViewById(R.id.bluetooth_textview);
+                    tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
+                }
+            });
+            parent.addView(bluetoothTile);
+        }
 
         // Brightness
         QuickSettingsTileView brightnessTile = (QuickSettingsTileView)
@@ -575,10 +336,9 @@
         brightnessTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                Intent intent = new Intent(android.provider.Settings.ACTION_DISPLAY_SETTINGS);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
+                // startSettingsActivity(android.provider.Settings.ACTION_DISPLAY_SETTINGS);
                 mBar.collapseAllPanels(true);
+                showBrightnessDialog();
             }
         });
         parent.addView(brightnessTile);
@@ -592,11 +352,7 @@
         locationTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                Intent intent =
-                        new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
-                mBar.collapseAllPanels(true);
+                startSettingsActivity(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
             }
         });
         mModel.addLocationTile(locationTile, new QuickSettingsModel.RefreshCallback() {
@@ -604,6 +360,7 @@
             public void refreshView(QuickSettingsTileView view, State state) {
                 TextView tv = (TextView) view.findViewById(R.id.location_textview);
                 tv.setText(state.label);
+                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
             }
         });
         parent.addView(locationTile);
@@ -615,8 +372,8 @@
         wifiDisplayTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                showWifiDisplayDialog();
                 mBar.collapseAllPanels(true);
+                showWifiDisplayDialog();
             }
         });
         mModel.addWifiDisplayTile(wifiDisplayTile, new QuickSettingsModel.RefreshCallback() {
@@ -624,6 +381,7 @@
             public void refreshView(QuickSettingsTileView view, State state) {
                 TextView tv = (TextView) view.findViewById(R.id.wifi_display_textview);
                 tv.setText(state.label);
+                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
             }
         });
         parent.addView(wifiDisplayTile);
@@ -656,7 +414,32 @@
         }
         mContainerView.requestLayout();
     }
+    
+    private void showBrightnessDialog() {
+        if (mBrightnessDialog == null) {
+            mBrightnessDialog = new Dialog(mContext);
+            mBrightnessDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+            mBrightnessDialog.setContentView(R.layout.quick_settings_brightness_dialog);
+            mBrightnessDialog.setCanceledOnTouchOutside(true);
+        
+            mBrightnessController = new BrightnessController(mContext,
+                    (ToggleSlider) mBrightnessDialog.findViewById(R.id.brightness_slider));
+            mBrightnessDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                @Override
+                public void onDismiss(DialogInterface dialog) {
+                    mBrightnessController = null;
+                }
+            });
+            
+            mBrightnessDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+            mBrightnessDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+        }
+        if (!mBrightnessDialog.isShowing()) {
+            mBrightnessDialog.show();
+        }
+    }
 
+    // Wifi Display
     private void showWifiDisplayDialog() {
         mDisplayManager.scanWifiDisplays();
         updateWifiDisplayStatus();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
new file mode 100644
index 0000000..aa40f3c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -0,0 +1,323 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.hardware.display.WifiDisplayStatus;
+import android.os.Handler;
+import android.provider.Settings;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
+import com.android.systemui.statusbar.policy.LocationController.LocationGpsStateChangeCallback;
+import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+
+
+class QuickSettingsModel implements BluetoothStateChangeCallback,
+        NetworkSignalChangedCallback,
+        BatteryStateChangeCallback,
+        LocationGpsStateChangeCallback {
+
+    /** Represents the state of a given attribute. */
+    static class State {
+        int iconId;
+        String label;
+        boolean enabled = false;
+    }
+    static class BatteryState extends State {
+        int batteryLevel;
+        boolean pluggedIn;
+    }
+
+    /** The callback to update a given tile. */
+    interface RefreshCallback {
+        public void refreshView(QuickSettingsTileView view, State state);
+    }
+
+    /** Broadcast receive to determine if there is an alarm set. */
+    private BroadcastReceiver mAlarmIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_ALARM_CHANGED)) {
+                onAlarmChanged(intent);
+                onNextAlarmChanged();
+            }
+        }
+    };
+
+    /** ContentObserver to determine the next alarm */
+    private class NextAlarmObserver extends ContentObserver {
+        public NextAlarmObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override public void onChange(boolean selfChange) {
+            onNextAlarmChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.registerContentObserver(
+                    Settings.System.getUriFor(Settings.System.NEXT_ALARM_FORMATTED), false, this);
+        }
+    }
+
+    private Context mContext;
+    private Handler mHandler;
+    private NextAlarmObserver mNextAlarmObserver;
+
+    private QuickSettingsTileView mUserTile;
+    private RefreshCallback mUserCallback;
+    private State mUserState = new State();
+
+    private QuickSettingsTileView mTimeTile;
+    private RefreshCallback mTimeAlarmCallback;
+    private State mTimeAlarmState = new State();
+
+    private QuickSettingsTileView mAirplaneModeTile;
+    private RefreshCallback mAirplaneModeCallback;
+    private State mAirplaneModeState = new State();
+
+    private QuickSettingsTileView mWifiTile;
+    private RefreshCallback mWifiCallback;
+    private State mWifiState = new State();
+
+    private QuickSettingsTileView mWifiDisplayTile;
+    private RefreshCallback mWifiDisplayCallback;
+    private State mWifiDisplayState = new State();
+
+    private QuickSettingsTileView mRSSITile;
+    private RefreshCallback mRSSICallback;
+    private State mRSSIState = new State();
+
+    private QuickSettingsTileView mBluetoothTile;
+    private RefreshCallback mBluetoothCallback;
+    private State mBluetoothState = new State();
+
+    private QuickSettingsTileView mBatteryTile;
+    private RefreshCallback mBatteryCallback;
+    private BatteryState mBatteryState = new BatteryState();
+
+    private QuickSettingsTileView mLocationTile;
+    private RefreshCallback mLocationCallback;
+    private State mLocationState = new State();
+
+    public QuickSettingsModel(Context context) {
+        mContext = context;
+        mHandler = new Handler();
+        mNextAlarmObserver = new NextAlarmObserver(mHandler);
+        mNextAlarmObserver.startObserving();
+
+        IntentFilter alarmIntentFilter = new IntentFilter();
+        alarmIntentFilter.addAction(Intent.ACTION_ALARM_CHANGED);
+        context.registerReceiver(mAlarmIntentReceiver, alarmIntentFilter);
+    }
+
+    // User
+    void addUserTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mUserTile = view;
+        mUserCallback = cb;
+        mUserCallback.refreshView(mUserTile, mUserState);
+    }
+    void setUserTileInfo(String name) {
+        mUserState.label = name;
+        mUserCallback.refreshView(mUserTile, mUserState);
+    }
+
+    // Time
+    void addTimeTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mTimeTile = view;
+        mTimeAlarmCallback = cb;
+        mTimeAlarmCallback.refreshView(view, mTimeAlarmState);
+    }
+    void onAlarmChanged(Intent intent) {
+        mTimeAlarmState.enabled = intent.getBooleanExtra("alarmSet", false);
+        System.out.println("ALARM ENABLED: " + mTimeAlarmState.enabled);
+        mTimeAlarmCallback.refreshView(mTimeTile, mTimeAlarmState);
+    }
+    void onNextAlarmChanged() {
+        mTimeAlarmState.label = Settings.System.getString(mContext.getContentResolver(),
+                Settings.System.NEXT_ALARM_FORMATTED);
+        System.out.println("ALARM LABEL: " + mTimeAlarmState.label);
+        mTimeAlarmCallback.refreshView(mTimeTile, mTimeAlarmState);
+    }
+
+    // Airplane Mode
+    void addAirplaneModeTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mAirplaneModeTile = view;
+        mAirplaneModeTile.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mAirplaneModeState.enabled) {
+                    setAirplaneModeState(false);
+                } else {
+                    setAirplaneModeState(true);
+                }
+            }
+        });
+        mAirplaneModeCallback = cb;
+        mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
+    }
+    private void setAirplaneModeState(boolean enabled) {
+        // TODO: Sets the view to be "awaiting" if not already awaiting
+
+        // Change the system setting
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
+                                enabled ? 1 : 0);
+
+        // Post the intent
+        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+        intent.putExtra("state", enabled);
+        mContext.sendBroadcast(intent);
+    }
+    // NetworkSignalChanged callback
+    @Override
+    public void onAirplaneModeChanged(boolean enabled) {
+        // TODO: If view is in awaiting state, disable
+        Resources r = mContext.getResources();
+        mAirplaneModeState.enabled = enabled;
+        mAirplaneModeState.iconId = (enabled ?
+                R.drawable.ic_qs_airplane_enabled :
+                R.drawable.ic_qs_airplane_normal);
+        mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
+    }
+
+    // Wifi
+    void addWifiTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mWifiTile = view;
+        mWifiCallback = cb;
+        mWifiCallback.refreshView(mWifiTile, mWifiState);
+    }
+    // NetworkSignalChanged callback
+    @Override
+    public void onWifiSignalChanged(boolean enabled, String description) {
+        // TODO: If view is in awaiting state, disable
+        Resources r = mContext.getResources();
+        // TODO: Check if wifi is enabled
+        mWifiState.enabled = enabled;
+        mWifiState.iconId = (enabled ?
+                R.drawable.ic_qs_wifi_enabled :
+                R.drawable.ic_qs_wifi_normal);
+        mWifiState.label = (enabled ?
+                description :
+                r.getString(R.string.quick_settings_wifi_no_network));
+        mWifiCallback.refreshView(mWifiTile, mWifiState);
+    }
+
+    // RSSI
+    void addRSSITile(QuickSettingsTileView view, RefreshCallback cb) {
+        mRSSITile = view;
+        mRSSICallback = cb;
+        mRSSICallback.refreshView(mRSSITile, mRSSIState);
+    }
+    // NetworkSignalChanged callback
+    @Override
+    public void onMobileDataSignalChanged(boolean enabled, String description) {
+        // TODO: If view is in awaiting state, disable
+        Resources r = mContext.getResources();
+        // TODO: Check if RSSI is enabled
+        mRSSIState.enabled = enabled;
+        mRSSIState.iconId = (enabled ?
+                R.drawable.ic_qs_rssi_enabled :
+                R.drawable.ic_qs_rssi_normal);
+        mRSSIState.label = (enabled ?
+                description :
+                r.getString(R.string.quick_settings_rssi_emergency_only));
+        mRSSICallback.refreshView(mRSSITile, mRSSIState);
+    }
+
+    // Bluetooth
+    void addBluetoothTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mBluetoothTile = view;
+        mBluetoothCallback = cb;
+
+        final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        onBluetoothStateChange(adapter.isEnabled());
+    }
+    boolean deviceSupportsBluetooth() {
+        return (BluetoothAdapter.getDefaultAdapter() != null);
+    }
+    // BluetoothController callback
+    @Override
+    public void onBluetoothStateChange(boolean on) {
+        // TODO: If view is in awaiting state, disable
+        Resources r = mContext.getResources();
+        mBluetoothState.enabled = on;
+        if (on) {
+            mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_enabled;
+        } else {
+            mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_normal;
+        }
+        mBluetoothCallback.refreshView(mBluetoothTile, mBluetoothState);
+    }
+
+    // Battery
+    void addBatteryTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mBatteryTile = view;
+        mBatteryCallback = cb;
+        mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
+    }
+    // BatteryController callback
+    @Override
+    public void onBatteryLevelChanged(int level, boolean pluggedIn) {
+        mBatteryState.batteryLevel = level;
+        mBatteryState.pluggedIn = pluggedIn;
+        mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
+    }
+
+    // Location
+    void addLocationTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mLocationTile = view;
+        mLocationCallback = cb;
+        mLocationCallback.refreshView(mLocationTile, mLocationState);
+    }
+    // LocationController callback
+    @Override
+    public void onLocationGpsStateChanged(boolean inUse, String description) {
+        mLocationState.enabled = inUse;
+        mLocationState.label = description;
+        mLocationCallback.refreshView(mLocationTile, mLocationState);
+    }
+
+    // Wifi Display
+    void addWifiDisplayTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mWifiDisplayTile = view;
+        mWifiDisplayCallback = cb;
+    }
+    public void onWifiDisplayStateChanged(WifiDisplayStatus status) {
+        mWifiDisplayState.enabled = status.isEnabled();
+        if (status.getActiveDisplay() != null) {
+            mWifiDisplayState.label = status.getActiveDisplay().getDeviceName();
+        } else {
+            mWifiDisplayState.label = mContext.getString(
+                    R.string.quick_settings_wifi_display_no_connection_label);
+        }
+        mWifiDisplayCallback.refreshView(mWifiDisplayTile, mWifiDisplayState);
+
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
index edad370..3c8276d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
@@ -74,7 +74,7 @@
 
     private boolean getAirplaneMode() {
         ContentResolver cr = mContext.getContentResolver();
-        return 0 != Settings.System.getInt(cr, Settings.System.AIRPLANE_MODE_ON, 0);
+        return 0 != Settings.Global.getInt(cr, Settings.Global.AIRPLANE_MODE_ON, 0);
     }
 
     // TODO: Fix this racy API by adding something better to TelephonyManager or
@@ -82,9 +82,9 @@
     private void unsafe(final boolean enabled) {
         AsyncTask.execute(new Runnable() {
                 public void run() {
-                    Settings.System.putInt(
+                    Settings.Global.putInt(
                             mContext.getContentResolver(),
-                            Settings.System.AIRPLANE_MODE_ON,
+                            Settings.Global.AIRPLANE_MODE_ON,
                             enabled ? 1 : 0);
                     Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
                     intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 4bf03e7..f864d04 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -127,6 +127,10 @@
                         n,
                         idOut,
                         UserHandle.USER_CURRENT);
+
+                for (LocationGpsStateChangeCallback cb : mChangeCallbacks) {
+                    cb.onLocationGpsStateChanged(true, text);
+                }
             } else {
                 mNotificationService.cancelNotificationWithTag(
                         mContext.getPackageName(), null,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 23f27e7..ea7235d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -509,8 +509,8 @@
     }
 
     private void updateAirplaneMode() {
-        mAirplaneMode = (Settings.System.getInt(mContext.getContentResolver(),
-            Settings.System.AIRPLANE_MODE_ON, 0) == 1);
+        mAirplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
+            Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
     }
 
     private final void updateTelephonySignalStrength() {
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 10f45a5..753b864 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -115,7 +115,7 @@
                 context.getSystemService(Context.CONNECTIVITY_SERVICE);
         mHasTelephony = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
         mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON), true,
+                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
                 mAirplaneModeObserver);
         Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = vibrator != null && vibrator.hasVibrator();
@@ -849,9 +849,9 @@
         // Let the service state callbacks handle the state.
         if (mHasTelephony) return;
 
-        boolean airplaneModeOn = Settings.System.getInt(
+        boolean airplaneModeOn = Settings.Global.getInt(
                 mContext.getContentResolver(),
-                Settings.System.AIRPLANE_MODE_ON,
+                Settings.Global.AIRPLANE_MODE_ON,
                 0) == 1;
         mAirplaneState = airplaneModeOn ? ToggleAction.State.On : ToggleAction.State.Off;
         mAirplaneModeOn.updateState(mAirplaneState);
@@ -861,9 +861,9 @@
      * Change the airplane mode system setting
      */
     private void changeAirplaneModeSystemSetting(boolean on) {
-        Settings.System.putInt(
+        Settings.Global.putInt(
                 mContext.getContentResolver(),
-                Settings.System.AIRPLANE_MODE_ON,
+                Settings.Global.AIRPLANE_MODE_ON,
                 on ? 1 : 0);
         Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index e170ec1..7fa662eeb 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -32,17 +32,17 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Rect;
 import android.os.UserManager;
-import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.animation.AnimationUtils;
-import android.widget.Button;
 import android.widget.RemoteViews.OnClickHandler;
 import android.widget.ViewFlipper;
 
@@ -51,7 +51,6 @@
 import com.android.internal.widget.LockPatternUtils;
 
 import java.io.File;
-import java.util.ArrayList;
 import java.util.List;
 
 public class KeyguardHostView extends KeyguardViewBase {
@@ -77,6 +76,8 @@
 
     private KeyguardSecurityModel mSecurityModel;
 
+    private Rect mTempRect = new Rect();
+
     public KeyguardHostView(Context context) {
         this(context, null);
     }
@@ -94,6 +95,17 @@
     }
 
     @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        boolean result = super.dispatchTouchEvent(ev);
+        mTempRect.set(0, 0, 0, 0);
+        offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect);
+        ev.offsetLocation(mTempRect.left, mTempRect.top);
+        result = mSecurityViewContainer.dispatchTouchEvent(ev) || result;
+        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+        return result;
+    }
+
+    @Override
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
         mViewMediatorCallback.keyguardDoneDrawing();
@@ -202,6 +214,17 @@
         dialog.show();
     }
 
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        if (event.getAction() == KeyEvent.ACTION_UP
+                && event.getKeyCode() == KeyEvent.KEYCODE_BACK
+                && mCurrentSecuritySelection != SecurityMode.None) {
+            mCallback.dismiss(false);
+            return true;
+        }
+        return super.dispatchKeyEvent(event);
+    }
+
     private void showTimeoutDialog() {
         int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
         int messageId = 0;
@@ -484,6 +507,11 @@
         if (DEBUG) Log.d(TAG, "screen on");
         showSecurityScreen(mCurrentSecuritySelection);
         getSecurityView(mCurrentSecuritySelection).onResume();
+
+        // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
+        // layout is blank but forcing a layout causes it to reappear (e.g. with with
+        // hierarchyviewer).
+        requestLayout();
     }
 
     @Override
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
index 3a32b5b..6de40e4 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
@@ -22,6 +22,7 @@
 import android.accounts.AuthenticatorException;
 import android.accounts.OperationCanceledException;
 import android.content.Context;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.CountDownTimer;
 import android.os.SystemClock;
@@ -31,7 +32,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.Button;
-import android.widget.LinearLayout;
+import android.widget.GridLayout;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.LockPatternView;
@@ -40,7 +41,7 @@
 import java.io.IOException;
 import java.util.List;
 
-public class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView {
+public class KeyguardPatternView extends GridLayout implements KeyguardSecurityView {
 
     private static final String TAG = "SecurityPatternView";
     private static final boolean DEBUG = false;
@@ -83,6 +84,7 @@
             mLockPatternView.clearPattern();
         }
     };
+    private Rect mTempRect = new Rect();
 
     enum FooterMode {
         Normal,
@@ -156,13 +158,18 @@
 
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
-        final boolean result = super.dispatchTouchEvent(ev);
+        boolean result = super.dispatchTouchEvent(ev);
         // as long as the user is entering a pattern (i.e sending a touch event that was handled
         // by this screen), keep poking the wake lock so that the screen will stay on.
         final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime;
         if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) {
             mLastPokeTime = SystemClock.elapsedRealtime();
         }
+        mTempRect.set(0, 0, 0, 0);
+        offsetRectIntoDescendantCoords(mLockPatternView, mTempRect);
+        ev.offsetLocation(mTempRect.left, mTempRect.top);
+        result = mLockPatternView.dispatchTouchEvent(ev) || result;
+        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
         return result;
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
new file mode 100644
index 0000000..911cfe0
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
@@ -0,0 +1,58 @@
+/*
+ * 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.policy.impl.keyguard;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ViewFlipper;
+
+/**
+ * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so
+ * we can emulate {@link WindowManager.LayoutParams#FLAG_SLIPPERY} within a view hierarchy.
+ *
+ */
+public class KeyguardSecurityViewFlipper extends ViewFlipper {
+    private Rect mTempRect = new Rect();
+
+    public KeyguardSecurityViewFlipper(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardSecurityViewFlipper(Context context, AttributeSet attr) {
+        super(context, attr);
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        boolean result = super.dispatchTouchEvent(ev);
+        mTempRect.set(0, 0, 0, 0);
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (child.getVisibility() == View.VISIBLE) {
+                offsetRectIntoDescendantCoords(child, mTempRect);
+                ev.offsetLocation(mTempRect.left, mTempRect.top);
+                result = child.dispatchTouchEvent(ev) || result;
+                ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+            }
+        }
+        return result;
+    }
+
+}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index 66c7c10..c48e2d7 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -73,9 +73,9 @@
     private static final int MSG_PHONE_STATE_CHANGED = 306;
     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_SWITCHED = 310;
-    protected static final int MSG_USER_REMOVED = 311;
+    private static final int MSG_DPM_STATE_CHANGED = 309;
+    private static final int MSG_USER_SWITCHED = 310;
+    private static final int MSG_USER_REMOVED = 311;
 
     private static KeyguardUpdateMonitor sInstance;
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
index 61003bf..d9088e0 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
@@ -214,9 +214,9 @@
      */
     public synchronized void reset() {
         if (DEBUG) Log.d(TAG, "reset()");
-        if (mKeyguardView != null) {
-            mKeyguardView.reset();
-        }
+        // User might have switched, check if we need to go back to keyguard
+        // TODO: It's preferable to stay and show the correct lockscreen or unlock if none
+        maybeCreateKeyguardLocked(shouldEnableScreenRotation());
     }
 
     public synchronized void onScreenTurnedOff() {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 3ee82f7..1f0f5ef 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -41,6 +41,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.util.EventLog;
@@ -161,6 +162,9 @@
     /** High level access to the power manager for WakeLocks */
     private PowerManager mPM;
 
+    /** UserManager for querying number of users */
+    private UserManager mUserManager;
+
     /**
      * Used to keep the device awake while the keyguard is showing, i.e for
      * calls to {@link #pokeWakelock()}
@@ -436,6 +440,7 @@
     public KeyguardViewMediator(Context context, LockPatternUtils lockPatternUtils) {
         mContext = context;
         mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mWakeLock = mPM.newWakeLock(
                 PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "keyguard");
         mWakeLock.setReferenceCounted(false);
@@ -779,7 +784,8 @@
             return;
         }
 
-        if (mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
+        if (mUserManager.getUsers().size() < 2
+                && mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
             return;
         }
diff --git a/services/common_time/common_clock_service.h b/services/common_time/common_clock_service.h
index a65e398..bd663f0 100644
--- a/services/common_time/common_clock_service.h
+++ b/services/common_time/common_clock_service.h
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-#include <common_time/ICommonClock.h>
-
 #ifndef ANDROID_COMMON_CLOCK_SERVICE_H
 #define ANDROID_COMMON_CLOCK_SERVICE_H
 
+#include <sys/socket.h>
+#include <common_time/ICommonClock.h>
+
 namespace android {
 
 class CommonTimeServer;
diff --git a/services/common_time/common_time_config_service.h b/services/common_time/common_time_config_service.h
index 8283c24..89806dd 100644
--- a/services/common_time/common_time_config_service.h
+++ b/services/common_time/common_time_config_service.h
@@ -13,11 +13,12 @@
  * limitations under the License.
  */
 
-#include <common_time/ICommonTimeConfig.h>
-
 #ifndef ANDROID_COMMON_TIME_CONFIG_SERVICE_H
 #define ANDROID_COMMON_TIME_CONFIG_SERVICE_H
 
+#include <sys/socket.h>
+#include <common_time/ICommonTimeConfig.h>
+
 namespace android {
 
 class String16;
diff --git a/services/common_time/common_time_server.h b/services/common_time/common_time_server.h
index f6a2419..6e18050 100644
--- a/services/common_time/common_time_server.h
+++ b/services/common_time/common_time_server.h
@@ -19,7 +19,7 @@
 
 #include <arpa/inet.h>
 #include <stdint.h>
-#include <linux/socket.h>
+#include <sys/socket.h>
 
 #include <common_time/ICommonClock.h>
 #include <common_time/local_clock.h>
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 8604f95..87a6c1b 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -166,6 +166,10 @@
     return true;
 }
 
+static bool isMainDisplay(int32_t displayId) {
+    return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
+}
+
 static void dumpRegion(String8& dump, const SkRegion& region) {
     if (region.isEmpty()) {
         dump.append("<empty>");
@@ -423,11 +427,12 @@
                 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
                 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
                 && mInputTargetWaitApplicationHandle != NULL) {
+            int32_t displayId = motionEntry->displayId;
             int32_t x = int32_t(motionEntry->pointerCoords[0].
                     getAxisValue(AMOTION_EVENT_AXIS_X));
             int32_t y = int32_t(motionEntry->pointerCoords[0].
                     getAxisValue(AMOTION_EVENT_AXIS_Y));
-            sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(x, y);
+            sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
             if (touchedWindowHandle != NULL
                     && touchedWindowHandle->inputApplicationHandle
                             != mInputTargetWaitApplicationHandle) {
@@ -444,28 +449,31 @@
     return needWake;
 }
 
-sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
+sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
+        int32_t x, int32_t y) {
     // Traverse windows from front to back to find touched window.
     size_t numWindows = mWindowHandles.size();
     for (size_t i = 0; i < numWindows; i++) {
         sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
         const InputWindowInfo* windowInfo = windowHandle->getInfo();
-        int32_t flags = windowInfo->layoutParamsFlags;
+        if (windowInfo->displayId == displayId) {
+            int32_t flags = windowInfo->layoutParamsFlags;
 
-        if (windowInfo->visible) {
-            if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
-                bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
-                        | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
-                if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
-                    // Found window.
-                    return windowHandle;
+            if (windowInfo->visible) {
+                if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
+                    bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
+                            | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
+                    if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
+                        // Found window.
+                        return windowHandle;
+                    }
                 }
             }
-        }
 
-        if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
-            // Error window is on top but not visible, so touch is dropped.
-            return NULL;
+            if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
+                // Error window is on top but not visible, so touch is dropped.
+                return NULL;
+            }
         }
     }
     return NULL;
@@ -826,7 +834,10 @@
         return true;
     }
 
-    addMonitoringTargetsLocked(inputTargets);
+    // TODO: support sending secondary display events to input monitors
+    if (isMainDisplay(entry->displayId)) {
+        addMonitoringTargetsLocked(inputTargets);
+    }
 
     // Dispatch the motion.
     if (conflictingPointerActions) {
@@ -1117,6 +1128,7 @@
     //
     bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
 
+    int32_t displayId = entry->displayId;
     int32_t action = entry->action;
     int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
 
@@ -1126,9 +1138,10 @@
     sp<InputWindowHandle> newHoverWindowHandle;
 
     bool isSplit = mTouchState.split;
-    bool switchedDevice = mTouchState.deviceId >= 0
+    bool switchedDevice = mTouchState.deviceId >= 0 && mTouchState.displayId >= 0
             && (mTouchState.deviceId != entry->deviceId
-                    || mTouchState.source != entry->source);
+                    || mTouchState.source != entry->source
+                    || mTouchState.displayId != displayId);
     bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
             || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
             || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
@@ -1152,6 +1165,7 @@
         mTempTouchState.down = down;
         mTempTouchState.deviceId = entry->deviceId;
         mTempTouchState.source = entry->source;
+        mTempTouchState.displayId = displayId;
         isSplit = false;
     } else {
         mTempTouchState.copyFrom(mTouchState);
@@ -1174,8 +1188,11 @@
         for (size_t i = 0; i < numWindows; i++) {
             sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
             const InputWindowInfo* windowInfo = windowHandle->getInfo();
-            int32_t flags = windowInfo->layoutParamsFlags;
+            if (windowInfo->displayId != displayId) {
+                continue; // wrong display
+            }
 
+            int32_t flags = windowInfo->layoutParamsFlags;
             if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
                 if (topErrorWindowHandle == NULL) {
                     topErrorWindowHandle = windowHandle;
@@ -1300,7 +1317,8 @@
 
             sp<InputWindowHandle> oldTouchedWindowHandle =
                     mTempTouchState.getFirstForegroundWindowHandle();
-            sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(x, y);
+            sp<InputWindowHandle> newTouchedWindowHandle =
+                    findTouchedWindowAtLocked(displayId, x, y);
             if (oldTouchedWindowHandle != newTouchedWindowHandle
                     && newTouchedWindowHandle != NULL) {
 #if DEBUG_FOCUS
@@ -1438,8 +1456,10 @@
         if (foregroundWindowHandle->getInfo()->hasWallpaper) {
             for (size_t i = 0; i < mWindowHandles.size(); i++) {
                 sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
-                if (windowHandle->getInfo()->layoutParamsType
-                        == InputWindowInfo::TYPE_WALLPAPER) {
+                const InputWindowInfo* info = windowHandle->getInfo();
+                if (info->displayId == displayId
+                        && windowHandle->getInfo()->layoutParamsType
+                                == InputWindowInfo::TYPE_WALLPAPER) {
                     mTempTouchState.addOrUpdateWindow(windowHandle,
                             InputTarget::FLAG_WINDOW_IS_OBSCURED
                                     | InputTarget::FLAG_DISPATCH_AS_IS,
@@ -1495,6 +1515,7 @@
                         || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
                     mTouchState.deviceId = entry->deviceId;
                     mTouchState.source = entry->source;
+                    mTouchState.displayId = displayId;
                 }
             } else if (maskedAction == AMOTION_EVENT_ACTION_UP
                     || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
@@ -1610,6 +1631,7 @@
 
 bool InputDispatcher::isWindowObscuredAtPointLocked(
         const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
+    int32_t displayId = windowHandle->getInfo()->displayId;
     size_t numWindows = mWindowHandles.size();
     for (size_t i = 0; i < numWindows; i++) {
         sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
@@ -1618,7 +1640,8 @@
         }
 
         const InputWindowInfo* otherInfo = otherHandle->getInfo();
-        if (otherInfo->visible && ! otherInfo->isTrustedOverlay()
+        if (otherInfo->displayId == displayId
+                && otherInfo->visible && !otherInfo->isTrustedOverlay()
                 && otherInfo->frameContainsPoint(x, y)) {
             return true;
         }
@@ -1845,7 +1868,7 @@
         }
         if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
                 && !connection->inputState.isHovering(
-                        motionEntry->deviceId, motionEntry->source)) {
+                        motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
 #if DEBUG_DISPATCH_CYCLE
         ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
                 connection->getInputChannelName());
@@ -2271,6 +2294,7 @@
             originalMotionEntry->xPrecision,
             originalMotionEntry->yPrecision,
             originalMotionEntry->downTime,
+            originalMotionEntry->displayId,
             splitPointerCount, splitPointerProperties, splitPointerCoords);
 
     if (originalMotionEntry->injectionState) {
@@ -2351,7 +2375,7 @@
     { // acquire lock
         mLock.lock();
 
-        if (mInputFilterEnabled) {
+        if (shouldSendKeyToInputFilterLocked(args)) {
             mLock.unlock();
 
             policyFlags |= POLICY_FLAG_FILTERED;
@@ -2377,6 +2401,10 @@
     }
 }
 
+bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
+    return mInputFilterEnabled;
+}
+
 void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
 #if DEBUG_INBOUND_EVENT_DETAILS
     ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
@@ -2415,7 +2443,7 @@
     { // acquire lock
         mLock.lock();
 
-        if (mInputFilterEnabled) {
+        if (shouldSendMotionToInputFilterLocked(args)) {
             mLock.unlock();
 
             MotionEvent event;
@@ -2438,6 +2466,7 @@
                 args->deviceId, args->source, policyFlags,
                 args->action, args->flags, args->metaState, args->buttonState,
                 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
+                args->displayId,
                 args->pointerCount, args->pointerProperties, args->pointerCoords);
 
         needWake = enqueueInboundEventLocked(newEntry);
@@ -2449,6 +2478,11 @@
     }
 }
 
+bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
+    // TODO: support sending secondary display events to input filter
+    return mInputFilterEnabled && isMainDisplay(args->displayId);
+}
+
 void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
 #if DEBUG_INBOUND_EVENT_DETAILS
     ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
@@ -2532,6 +2566,7 @@
 
     case AINPUT_EVENT_TYPE_MOTION: {
         const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
+        int32_t displayId = ADISPLAY_ID_DEFAULT;
         int32_t action = motionEvent->getAction();
         size_t pointerCount = motionEvent->getPointerCount();
         const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
@@ -2553,8 +2588,8 @@
                 motionEvent->getMetaState(), motionEvent->getButtonState(),
                 motionEvent->getEdgeFlags(),
                 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
-                motionEvent->getDownTime(), uint32_t(pointerCount),
-                pointerProperties, samplePointerCoords);
+                motionEvent->getDownTime(), displayId,
+                uint32_t(pointerCount), pointerProperties, samplePointerCoords);
         lastInjectedEntry = firstInjectedEntry;
         for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
             sampleEventTimes += 1;
@@ -2565,8 +2600,8 @@
                     motionEvent->getMetaState(), motionEvent->getButtonState(),
                     motionEvent->getEdgeFlags(),
                     motionEvent->getXPrecision(), motionEvent->getYPrecision(),
-                    motionEvent->getDownTime(), uint32_t(pointerCount),
-                    pointerProperties, samplePointerCoords);
+                    motionEvent->getDownTime(), displayId,
+                    uint32_t(pointerCount), pointerProperties, samplePointerCoords);
             lastInjectedEntry->next = nextInjectedEntry;
             lastInjectedEntry = nextInjectedEntry;
         }
@@ -2939,6 +2974,12 @@
 #endif
             return true;
         }
+        if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
+#if DEBUG_FOCUS
+            ALOGD("Cannot transfer focus because windows are on different displays.");
+#endif
+            return false;
+        }
 
         bool found = false;
         for (size_t i = 0; i < mTouchState.windows.size(); i++) {
@@ -3040,6 +3081,7 @@
     dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
     dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
     dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
+    dump.appendFormat(INDENT "TouchDisplayId: %d\n", mTouchState.displayId);
     if (!mTouchState.windows.isEmpty()) {
         dump.append(INDENT "TouchedWindows:\n");
         for (size_t i = 0; i < mTouchState.windows.size(); i++) {
@@ -3059,11 +3101,12 @@
             const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
             const InputWindowInfo* windowInfo = windowHandle->getInfo();
 
-            dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
+            dump.appendFormat(INDENT2 "%d: name='%s', displayId=%d, "
+                    "paused=%s, hasFocus=%s, hasWallpaper=%s, "
                     "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
                     "frame=[%d,%d][%d,%d], scale=%f, "
                     "touchableRegion=",
-                    i, windowInfo->name.string(),
+                    i, windowInfo->name.string(), windowInfo->displayId,
                     toString(windowInfo->paused),
                     toString(windowInfo->hasFocus),
                     toString(windowInfo->hasWallpaper),
@@ -3802,14 +3845,14 @@
         int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
         int32_t metaState, int32_t buttonState,
         int32_t edgeFlags, float xPrecision, float yPrecision,
-        nsecs_t downTime, uint32_t pointerCount,
+        nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
         const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
         EventEntry(TYPE_MOTION, eventTime, policyFlags),
         eventTime(eventTime),
         deviceId(deviceId), source(source), action(action), flags(flags),
         metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
         xPrecision(xPrecision), yPrecision(yPrecision),
-        downTime(downTime), pointerCount(pointerCount) {
+        downTime(downTime), displayId(displayId), pointerCount(pointerCount) {
     for (uint32_t i = 0; i < pointerCount; i++) {
         this->pointerProperties[i].copyFrom(pointerProperties[i]);
         this->pointerCoords[i].copyFrom(pointerCoords[i]);
@@ -3820,8 +3863,8 @@
 }
 
 void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
-    msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x)",
-            action, deviceId, source);
+    msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x, displayId=%d)",
+            action, deviceId, source, displayId);
 }
 
 
@@ -3864,11 +3907,13 @@
     return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
 }
 
-bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source) const {
+bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
+        int32_t displayId) const {
     for (size_t i = 0; i < mMotionMementos.size(); i++) {
         const MotionMemento& memento = mMotionMementos.itemAt(i);
         if (memento.deviceId == deviceId
                 && memento.source == source
+                && memento.displayId == displayId
                 && memento.hovering) {
             return true;
         }
@@ -4025,6 +4070,7 @@
         const MotionMemento& memento = mMotionMementos.itemAt(i);
         if (memento.deviceId == entry->deviceId
                 && memento.source == entry->source
+                && memento.displayId == entry->displayId
                 && memento.hovering == hovering) {
             return i;
         }
@@ -4055,6 +4101,7 @@
     memento.xPrecision = entry->xPrecision;
     memento.yPrecision = entry->yPrecision;
     memento.downTime = entry->downTime;
+    memento.displayId = entry->displayId;
     memento.setPointers(entry);
     memento.hovering = hovering;
     memento.policyFlags = entry->policyFlags;
@@ -4090,6 +4137,7 @@
                             : AMOTION_EVENT_ACTION_CANCEL,
                     memento.flags, 0, 0, 0,
                     memento.xPrecision, memento.yPrecision, memento.downTime,
+                    memento.displayId,
                     memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
         }
     }
@@ -4108,7 +4156,8 @@
             for (size_t j = 0; j < other.mMotionMementos.size(); ) {
                 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
                 if (memento.deviceId == otherMemento.deviceId
-                        && memento.source == otherMemento.source) {
+                        && memento.source == otherMemento.source
+                        && memento.displayId == otherMemento.displayId) {
                     other.mMotionMementos.removeAt(j);
                 } else {
                     j += 1;
@@ -4240,7 +4289,7 @@
 // --- InputDispatcher::TouchState ---
 
 InputDispatcher::TouchState::TouchState() :
-    down(false), split(false), deviceId(-1), source(0) {
+    down(false), split(false), deviceId(-1), source(0), displayId(-1) {
 }
 
 InputDispatcher::TouchState::~TouchState() {
@@ -4251,6 +4300,7 @@
     split = false;
     deviceId = -1;
     source = 0;
+    displayId = -1;
     windows.clear();
 }
 
@@ -4259,6 +4309,7 @@
     split = other.split;
     deviceId = other.deviceId;
     source = other.source;
+    displayId = other.displayId;
     windows = other.windows;
 }
 
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index d0824fc..af7ff5e 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -511,15 +511,17 @@
         float xPrecision;
         float yPrecision;
         nsecs_t downTime;
+        int32_t displayId;
         uint32_t pointerCount;
         PointerProperties pointerProperties[MAX_POINTERS];
         PointerCoords pointerCoords[MAX_POINTERS];
 
         MotionEntry(nsecs_t eventTime,
-                int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
-                int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+                int32_t deviceId, uint32_t source, uint32_t policyFlags,
+                int32_t action, int32_t flags,
+                int32_t metaState, int32_t buttonState, int32_t edgeFlags,
                 float xPrecision, float yPrecision,
-                nsecs_t downTime, uint32_t pointerCount,
+                nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
                 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
         virtual void appendDescription(String8& msg) const;
 
@@ -696,7 +698,7 @@
 
         // Returns true if the specified source is known to have received a hover enter
         // motion event.
-        bool isHovering(int32_t deviceId, uint32_t source) const;
+        bool isHovering(int32_t deviceId, uint32_t source, int32_t displayId) const;
 
         // Records tracking information for a key event that has just been published.
         // Returns true if the event should be delivered, false if it is inconsistent
@@ -752,6 +754,7 @@
             float xPrecision;
             float yPrecision;
             nsecs_t downTime;
+            int32_t displayId;
             uint32_t pointerCount;
             PointerProperties pointerProperties[MAX_POINTERS];
             PointerCoords pointerCoords[MAX_POINTERS];
@@ -867,7 +870,7 @@
     // to transfer focus to a new application.
     EventEntry* mNextUnblockedEvent;
 
-    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t x, int32_t y);
+    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y);
 
     // All registered connections mapped by channel file descriptor.
     KeyedVector<int, sp<Connection> > mConnectionsByFd;
@@ -899,6 +902,10 @@
     bool runCommandsLockedInterruptible();
     CommandEntry* postCommandLocked(Command command);
 
+    // Input filter processing.
+    bool shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args);
+    bool shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args);
+
     // Inbound event processing.
     void drainInboundQueueLocked();
     void releasePendingEventLocked();
@@ -928,6 +935,7 @@
         bool split;
         int32_t deviceId; // id of the device that is currently down, others are rejected
         uint32_t source;  // source of the device that is current down, others are rejected
+        int32_t displayId; // id to the display that currently has a touch, others are rejected
         Vector<TouchedWindow> windows;
 
         TouchState();
diff --git a/services/input/InputListener.cpp b/services/input/InputListener.cpp
index 657a6b9..c2705b0 100644
--- a/services/input/InputListener.cpp
+++ b/services/input/InputListener.cpp
@@ -69,12 +69,12 @@
 NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
         uint32_t policyFlags,
         int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
-        int32_t edgeFlags, uint32_t pointerCount,
+        int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
         const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
         float xPrecision, float yPrecision, nsecs_t downTime) :
         eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
         action(action), flags(flags), metaState(metaState), buttonState(buttonState),
-        edgeFlags(edgeFlags), pointerCount(pointerCount),
+        edgeFlags(edgeFlags), displayId(displayId), pointerCount(pointerCount),
         xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
     for (uint32_t i = 0; i < pointerCount; i++) {
         this->pointerProperties[i].copyFrom(pointerProperties[i]);
@@ -87,7 +87,8 @@
         policyFlags(other.policyFlags),
         action(other.action), flags(other.flags),
         metaState(other.metaState), buttonState(other.buttonState),
-        edgeFlags(other.edgeFlags), pointerCount(other.pointerCount),
+        edgeFlags(other.edgeFlags), displayId(other.displayId),
+        pointerCount(other.pointerCount),
         xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
     for (uint32_t i = 0; i < pointerCount; i++) {
         pointerProperties[i].copyFrom(other.pointerProperties[i]);
diff --git a/services/input/InputListener.h b/services/input/InputListener.h
index b1dc0b8..486852b 100644
--- a/services/input/InputListener.h
+++ b/services/input/InputListener.h
@@ -88,6 +88,7 @@
     int32_t metaState;
     int32_t buttonState;
     int32_t edgeFlags;
+    int32_t displayId;
     uint32_t pointerCount;
     PointerProperties pointerProperties[MAX_POINTERS];
     PointerCoords pointerCoords[MAX_POINTERS];
@@ -99,7 +100,7 @@
 
     NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
             int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
-            int32_t edgeFlags, uint32_t pointerCount,
+            int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
             const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
             float xPrecision, float yPrecision, nsecs_t downTime);
 
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 513dc13..d56b9a9 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -2431,6 +2431,7 @@
 
     mPointerVelocityControl.move(when, &deltaX, &deltaY);
 
+    int32_t displayId;
     if (mPointerController != NULL) {
         if (moved || scrolled || buttonsChanged) {
             mPointerController->setPresentation(
@@ -2451,9 +2452,11 @@
         mPointerController->getPosition(&x, &y);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+        displayId = ADISPLAY_ID_DEFAULT;
     } else {
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+        displayId = ADISPLAY_ID_NONE;
     }
 
     pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
@@ -2485,7 +2488,8 @@
 
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
                 motionEventAction, 0, metaState, currentButtonState, 0,
-                1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+                displayId, 1, &pointerProperties, &pointerCoords,
+                mXPrecision, mYPrecision, downTime);
         getListener()->notifyMotion(&args);
 
         // Send hover move after UP to tell the application that the mouse is hovering now.
@@ -2494,7 +2498,8 @@
             NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
                     AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
                     metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
-                    1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+                    displayId, 1, &pointerProperties, &pointerCoords,
+                    mXPrecision, mYPrecision, downTime);
             getListener()->notifyMotion(&hoverArgs);
         }
 
@@ -2506,7 +2511,8 @@
             NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
                     AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
                     AMOTION_EVENT_EDGE_FLAG_NONE,
-                    1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+                    displayId, 1, &pointerProperties, &pointerCoords,
+                    mXPrecision, mYPrecision, downTime);
             getListener()->notifyMotion(&scrollArgs);
         }
     }
@@ -2539,7 +2545,8 @@
 TouchInputMapper::TouchInputMapper(InputDevice* device) :
         InputMapper(device),
         mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
-        mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1) {
+        mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
+        mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
 }
 
 TouchInputMapper::~TouchInputMapper() {
@@ -2601,6 +2608,8 @@
     dumpSurface(dump);
 
     dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
+    dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
+    dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
     dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
     dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
     dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
@@ -2810,7 +2819,7 @@
         ALOG_ASSERT(false);
     }
 
-    dump.appendFormat(INDENT4 "AssociatedDisplay: present=%s, isExternal=%s\n",
+    dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
             toString(mParameters.hasAssociatedDisplay),
             toString(mParameters.associatedDisplayIsExternal));
     dump.appendFormat(INDENT4 "OrientationAware: %s\n",
@@ -2869,10 +2878,15 @@
         return;
     }
 
+    // Raw width and height in the natural orientation.
+    int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+    int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
+
     // Get associated display dimensions.
+    bool viewportChanged = false;
+    DisplayViewport newViewport;
     if (mParameters.hasAssociatedDisplay) {
-        if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal,
-                &mAssociatedDisplayViewport)) {
+        if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
             ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
                     "display.  The device will be inoperable until the display size "
                     "becomes available.",
@@ -2880,25 +2894,77 @@
             mDeviceMode = DEVICE_MODE_DISABLED;
             return;
         }
-    }
-
-    // Configure dimensions.
-    int32_t width, height, orientation;
-    if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
-        width = mAssociatedDisplayViewport.logicalRight - mAssociatedDisplayViewport.logicalLeft;
-        height = mAssociatedDisplayViewport.logicalBottom - mAssociatedDisplayViewport.logicalTop;
-        if (mAssociatedDisplayViewport.orientation == DISPLAY_ORIENTATION_90
-                || mAssociatedDisplayViewport.orientation == DISPLAY_ORIENTATION_270) {
-            int32_t temp = height;
-            height = width;
-            width = temp;
-        }
-        orientation = mParameters.orientationAware ?
-                mAssociatedDisplayViewport.orientation : DISPLAY_ORIENTATION_0;
     } else {
-        width = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
-        height = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
-        orientation = DISPLAY_ORIENTATION_0;
+        newViewport.setNonDisplayViewport(rawWidth, rawHeight);
+    }
+    if (mViewport != newViewport) {
+        mViewport = newViewport;
+        viewportChanged = true;
+
+        if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
+            // Convert rotated viewport to natural surface coordinates.
+            int32_t naturalLogicalWidth, naturalLogicalHeight;
+            int32_t naturalPhysicalWidth, naturalPhysicalHeight;
+            int32_t naturalPhysicalLeft, naturalPhysicalTop;
+            int32_t naturalDeviceWidth, naturalDeviceHeight;
+            switch (mViewport.orientation) {
+            case DISPLAY_ORIENTATION_90:
+                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
+                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
+                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
+                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
+                naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
+                naturalPhysicalTop = mViewport.physicalLeft;
+                naturalDeviceWidth = mViewport.deviceHeight;
+                naturalDeviceHeight = mViewport.deviceWidth;
+                break;
+            case DISPLAY_ORIENTATION_180:
+                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
+                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
+                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
+                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
+                naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
+                naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
+                naturalDeviceWidth = mViewport.deviceWidth;
+                naturalDeviceHeight = mViewport.deviceHeight;
+                break;
+            case DISPLAY_ORIENTATION_270:
+                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
+                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
+                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
+                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
+                naturalPhysicalLeft = mViewport.physicalTop;
+                naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
+                naturalDeviceWidth = mViewport.deviceHeight;
+                naturalDeviceHeight = mViewport.deviceWidth;
+                break;
+            case DISPLAY_ORIENTATION_0:
+            default:
+                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
+                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
+                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
+                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
+                naturalPhysicalLeft = mViewport.physicalLeft;
+                naturalPhysicalTop = mViewport.physicalTop;
+                naturalDeviceWidth = mViewport.deviceWidth;
+                naturalDeviceHeight = mViewport.deviceHeight;
+                break;
+            }
+
+            mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
+            mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
+            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
+            mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
+
+            mSurfaceOrientation = mParameters.orientationAware ?
+                    mViewport.orientation : DISPLAY_ORIENTATION_0;
+        } else {
+            mSurfaceWidth = rawWidth;
+            mSurfaceHeight = rawHeight;
+            mSurfaceLeft = 0;
+            mSurfaceTop = 0;
+            mSurfaceOrientation = DISPLAY_ORIENTATION_0;
+        }
     }
 
     // If moving between pointer modes, need to reset some state.
@@ -2918,22 +2984,17 @@
         mPointerController.clear();
     }
 
-    bool orientationChanged = mSurfaceOrientation != orientation;
-    if (orientationChanged) {
-        mSurfaceOrientation = orientation;
-    }
-
-    bool sizeChanged = mSurfaceWidth != width || mSurfaceHeight != height;
-    if (sizeChanged || deviceModeChanged) {
-        ALOGI("Device reconfigured: id=%d, name='%s', surface size is now %dx%d, mode is %d",
-                getDeviceId(), getDeviceName().string(), width, height, mDeviceMode);
-
-        mSurfaceWidth = width;
-        mSurfaceHeight = height;
+    if (viewportChanged || deviceModeChanged) {
+        ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
+                "display id %d",
+                getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
+                mSurfaceOrientation, mDeviceMode, mViewport.displayId);
 
         // Configure X and Y factors.
-        mXScale = float(width) / (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1);
-        mYScale = float(height) / (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1);
+        mXScale = float(mSurfaceWidth) / rawWidth;
+        mYScale = float(mSurfaceHeight) / rawHeight;
+        mXTranslate = -mSurfaceLeft;
+        mYTranslate = -mSurfaceTop;
         mXPrecision = 1.0f / mXScale;
         mYPrecision = 1.0f / mYScale;
 
@@ -2950,7 +3011,7 @@
         mGeometricScale = avg(mXScale, mYScale);
 
         // Size of diagonal axis.
-        float diagonalSize = hypotf(width, height);
+        float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
 
         // Size factors.
         if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
@@ -3102,50 +3163,38 @@
             mOrientedRanges.distance.fuzz =
                     mRawPointerAxes.distance.fuzz * mDistanceScale;
         }
-    }
 
-    if (orientationChanged || sizeChanged || deviceModeChanged) {
-        // Compute oriented surface dimensions, precision, scales and ranges.
+        // Compute oriented precision, scales and ranges.
         // Note that the maximum value reported is an inclusive maximum value so it is one
         // unit less than the total width or height of surface.
         switch (mSurfaceOrientation) {
         case DISPLAY_ORIENTATION_90:
         case DISPLAY_ORIENTATION_270:
-            mOrientedSurfaceWidth = mSurfaceHeight;
-            mOrientedSurfaceHeight = mSurfaceWidth;
-
             mOrientedXPrecision = mYPrecision;
             mOrientedYPrecision = mXPrecision;
 
-            mOrientedRanges.x.min = 0;
-            mOrientedRanges.x.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
-                    * mYScale;
+            mOrientedRanges.x.min = mYTranslate;
+            mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
             mOrientedRanges.x.flat = 0;
             mOrientedRanges.x.fuzz = mYScale;
 
-            mOrientedRanges.y.min = 0;
-            mOrientedRanges.y.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
-                    * mXScale;
+            mOrientedRanges.y.min = mXTranslate;
+            mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
             mOrientedRanges.y.flat = 0;
             mOrientedRanges.y.fuzz = mXScale;
             break;
 
         default:
-            mOrientedSurfaceWidth = mSurfaceWidth;
-            mOrientedSurfaceHeight = mSurfaceHeight;
-
             mOrientedXPrecision = mXPrecision;
             mOrientedYPrecision = mYPrecision;
 
-            mOrientedRanges.x.min = 0;
-            mOrientedRanges.x.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
-                    * mXScale;
+            mOrientedRanges.x.min = mXTranslate;
+            mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
             mOrientedRanges.x.flat = 0;
             mOrientedRanges.x.fuzz = mXScale;
 
-            mOrientedRanges.y.min = 0;
-            mOrientedRanges.y.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
-                    * mYScale;
+            mOrientedRanges.y.min = mYTranslate;
+            mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
             mOrientedRanges.y.flat = 0;
             mOrientedRanges.y.fuzz = mYScale;
             break;
@@ -3153,10 +3202,8 @@
 
         // Compute pointer gesture detection parameters.
         if (mDeviceMode == DEVICE_MODE_POINTER) {
-            int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
-            int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
             float rawDiagonal = hypotf(rawWidth, rawHeight);
-            float displayDiagonal = hypotf(width, height);
+            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
 
             // Scale movements such that one whole swipe of the touch pad covers a
             // given area relative to the diagonal size of the display when no acceleration
@@ -3191,8 +3238,21 @@
 }
 
 void TouchInputMapper::dumpSurface(String8& dump) {
+    dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
+            "logicalFrame=[%d, %d, %d, %d], "
+            "physicalFrame=[%d, %d, %d, %d], "
+            "deviceSize=[%d, %d]\n",
+            mViewport.displayId, mViewport.orientation,
+            mViewport.logicalLeft, mViewport.logicalTop,
+            mViewport.logicalRight, mViewport.logicalBottom,
+            mViewport.physicalLeft, mViewport.physicalTop,
+            mViewport.physicalRight, mViewport.physicalBottom,
+            mViewport.deviceWidth, mViewport.deviceHeight);
+
     dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
     dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
+    dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
+    dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
     dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
 }
 
@@ -4087,28 +4147,28 @@
         float x, y;
         switch (mSurfaceOrientation) {
         case DISPLAY_ORIENTATION_90:
-            x = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
-            y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
+            x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+            y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
             orientation -= M_PI_2;
             if (orientation < - M_PI_2) {
                 orientation += M_PI;
             }
             break;
         case DISPLAY_ORIENTATION_180:
-            x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
-            y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
+            x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
+            y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
             break;
         case DISPLAY_ORIENTATION_270:
-            x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
-            y = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
+            x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
+            y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
             orientation += M_PI_2;
             if (orientation > M_PI_2) {
                 orientation -= M_PI;
             }
             break;
         default:
-            x = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
-            y = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
+            x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+            y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
             break;
         }
 
@@ -4364,7 +4424,8 @@
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
                 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
-                1, &pointerProperties, &pointerCoords, 0, 0, mPointerGesture.downTime);
+                mViewport.displayId, 1, &pointerProperties, &pointerCoords,
+                0, 0, mPointerGesture.downTime);
         getListener()->notifyMotion(&args);
     }
 
@@ -5272,6 +5333,7 @@
         // Send up.
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
                  AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
+                 mViewport.displayId,
                  1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
                  mOrientedXPrecision, mOrientedYPrecision,
                  mPointerSimple.downTime);
@@ -5284,6 +5346,7 @@
         // Send hover exit.
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
                 AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
+                mViewport.displayId,
                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
                 mOrientedXPrecision, mOrientedYPrecision,
                 mPointerSimple.downTime);
@@ -5298,6 +5361,7 @@
             // Send down.
             NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
                     AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
+                    mViewport.displayId,
                     1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
                     mOrientedXPrecision, mOrientedYPrecision,
                     mPointerSimple.downTime);
@@ -5307,6 +5371,7 @@
         // Send move.
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
                 AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
+                mViewport.displayId,
                 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
                 mOrientedXPrecision, mOrientedYPrecision,
                 mPointerSimple.downTime);
@@ -5320,6 +5385,7 @@
             // Send hover enter.
             NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
                     AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
+                    mViewport.displayId,
                     1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
                     mOrientedXPrecision, mOrientedYPrecision,
                     mPointerSimple.downTime);
@@ -5329,6 +5395,7 @@
         // Send hover move.
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
+                mViewport.displayId,
                 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
                 mOrientedXPrecision, mOrientedYPrecision,
                 mPointerSimple.downTime);
@@ -5349,6 +5416,7 @@
 
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
                 AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
+                mViewport.displayId,
                 1, &mPointerSimple.currentProperties, &pointerCoords,
                 mOrientedXPrecision, mOrientedYPrecision,
                 mPointerSimple.downTime);
@@ -5410,7 +5478,8 @@
 
     NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
             action, flags, metaState, buttonState, edgeFlags,
-            pointerCount, pointerProperties, pointerCoords, xPrecision, yPrecision, downTime);
+            mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
+            xPrecision, yPrecision, downTime);
     getListener()->notifyMotion(&args);
 }
 
@@ -6213,7 +6282,7 @@
         }
     }
 
-    // Moving a joystick axis should not wake the devide because joysticks can
+    // Moving a joystick axis should not wake the device because joysticks can
     // be fairly noisy even when not in use.  On the other hand, pushing a gamepad
     // button will likely wake the device.
     // TODO: Use the input device configuration to control this behavior more finely.
@@ -6221,7 +6290,7 @@
 
     NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
             AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
-            1, &pointerProperties, &pointerCoords, 0, 0, 0);
+            ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
     getListener()->notifyMotion(&args);
 }
 
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index e345a5fb..e1a8dd8 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -62,11 +62,14 @@
     int32_t physicalTop;
     int32_t physicalRight;
     int32_t physicalBottom;
+    int32_t deviceWidth;
+    int32_t deviceHeight;
 
     DisplayViewport() :
-            displayId(-1), orientation(DISPLAY_ORIENTATION_0),
+            displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0),
             logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0),
-            physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0) {
+            physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0),
+            deviceWidth(0), deviceHeight(0) {
     }
 
     bool operator==(const DisplayViewport& other) const {
@@ -79,12 +82,33 @@
                 && physicalLeft == other.physicalLeft
                 && physicalTop == other.physicalTop
                 && physicalRight == other.physicalRight
-                && physicalBottom == other.physicalBottom;
+                && physicalBottom == other.physicalBottom
+                && deviceWidth == other.deviceWidth
+                && deviceHeight == other.deviceHeight;
     }
 
     bool operator!=(const DisplayViewport& other) const {
         return !(*this == other);
     }
+
+    inline bool isValid() const {
+        return displayId >= 0;
+    }
+
+    void setNonDisplayViewport(int32_t width, int32_t height) {
+        displayId = ADISPLAY_ID_NONE;
+        orientation = DISPLAY_ORIENTATION_0;
+        logicalLeft = 0;
+        logicalTop = 0;
+        logicalRight = width;
+        logicalBottom = height;
+        physicalLeft = 0;
+        physicalTop = 0;
+        physicalRight = width;
+        physicalBottom = height;
+        deviceWidth = width;
+        deviceHeight = height;
+    }
 };
 
 /*
@@ -1297,18 +1321,30 @@
     virtual void syncTouch(nsecs_t when, bool* outHavePointerIds) = 0;
 
 private:
-    // The surface orientation and width and height set by configureSurface().
-    int32_t mSurfaceOrientation;
+    // The current viewport.
+    // The components of the viewport are specified in the display's rotated orientation.
+    DisplayViewport mViewport;
+
+    // The surface orientation, width and height set by configureSurface().
+    // The width and height are derived from the viewport but are specified
+    // in the natural orientation.
+    // The surface origin specifies how the surface coordinates should be translated
+    // to align with the logical display coordinate space.
+    // The orientation may be different from the viewport orientation as it specifies
+    // the rotation of the surface coordinates required to produce the viewport's
+    // requested orientation, so it will depend on whether the device is orientation aware.
     int32_t mSurfaceWidth;
     int32_t mSurfaceHeight;
-
-    // The associated display viewport set by configureSurface().
-    DisplayViewport mAssociatedDisplayViewport;
+    int32_t mSurfaceLeft;
+    int32_t mSurfaceTop;
+    int32_t mSurfaceOrientation;
 
     // Translation and scaling factors, orientation-independent.
+    float mXTranslate;
     float mXScale;
     float mXPrecision;
 
+    float mYTranslate;
     float mYScale;
     float mYPrecision;
 
@@ -1369,8 +1405,6 @@
     } mOrientedRanges;
 
     // Oriented dimensions and precision.
-    float mOrientedSurfaceWidth;
-    float mOrientedSurfaceHeight;
     float mOrientedXPrecision;
     float mOrientedYPrecision;
 
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index 824a64b..3118099 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -132,6 +132,7 @@
     int32_t ownerPid;
     int32_t ownerUid;
     int32_t inputFeatures;
+    int32_t displayId;
 
     bool touchableRegionContainsPoint(int32_t x, int32_t y) const;
     bool frameContainsPoint(int32_t x, int32_t y) const;
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 03516af..c6dbbf3 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -151,6 +151,8 @@
         v.physicalTop = 0;
         v.physicalRight = isRotated ? height : width;
         v.physicalBottom = isRotated ? width : height;
+        v.deviceWidth = isRotated ? height : width;
+        v.deviceHeight = isRotated ? width : height;
         mConfig.setDisplayInfo(false /*external*/, v);
         mConfig.setDisplayInfo(true /*external*/, v);
     }
@@ -487,6 +489,7 @@
                 return OK;
             }
         }
+        outAxisInfo->clear();
         return -1;
     }
 
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 343e70d..385681e 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -215,15 +215,18 @@
     }
 
     @Override
-    public void bindAppWidgetId(int appWidgetId, ComponentName provider) throws RemoteException {
-        getImplForUser(UserHandle.getCallingUserId()).bindAppWidgetId(appWidgetId, provider);
+    public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options)
+            throws RemoteException {
+        getImplForUser(UserHandle.getCallingUserId()).bindAppWidgetId(appWidgetId, provider,
+                options);
     }
 
     @Override
     public boolean bindAppWidgetIdIfAllowed(
-            String packageName, int appWidgetId, ComponentName provider) throws RemoteException {
+            String packageName, int appWidgetId, ComponentName provider, Bundle options)
+                    throws RemoteException {
         return getImplForUser(UserHandle.getCallingUserId()).bindAppWidgetIdIfAllowed(
-                packageName, appWidgetId, provider);
+                packageName, appWidgetId, provider, options);
     }
 
     @Override
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index 57ab921..95d7623 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -316,6 +316,8 @@
                 pw.print(info.updatePeriodMillis);
                 pw.print(" resizeMode=");
                 pw.print(info.resizeMode);
+                pw.print(info.widgetCategory);
+                pw.print(info.widgetFeatures);
                 pw.print(" autoAdvanceViewId=");
                 pw.print(info.autoAdvanceViewId);
                 pw.print(" initialLayout=#");
@@ -527,7 +529,7 @@
         }
     }
 
-    private void bindAppWidgetIdImpl(int appWidgetId, ComponentName provider) {
+    private void bindAppWidgetIdImpl(int appWidgetId, ComponentName provider, Bundle options) {
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mAppWidgetIds) {
@@ -550,6 +552,17 @@
                 }
 
                 id.provider = p;
+                if (options == null) {
+                    options = new Bundle();
+                }
+                id.options = options;
+
+                // We need to provide a default value for the widget category if it is not specified
+                if (!options.containsKey(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)) {
+                    options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+                            AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
+                }
+
                 p.instances.add(id);
                 int instancesSize = p.instances.size();
                 if (instancesSize == 1) {
@@ -572,14 +585,14 @@
         }
     }
 
-    public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
+    public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
         mContext.enforceCallingPermission(android.Manifest.permission.BIND_APPWIDGET,
             "bindAppWidgetId appWidgetId=" + appWidgetId + " provider=" + provider);
-        bindAppWidgetIdImpl(appWidgetId, provider);
+        bindAppWidgetIdImpl(appWidgetId, provider, options);
     }
 
     public boolean bindAppWidgetIdIfAllowed(
-            String packageName, int appWidgetId, ComponentName provider) {
+            String packageName, int appWidgetId, ComponentName provider, Bundle options) {
         try {
             mContext.enforceCallingPermission(android.Manifest.permission.BIND_APPWIDGET, null);
         } catch (SecurityException se) {
@@ -587,7 +600,7 @@
                 return false;
             }
         }
-        bindAppWidgetIdImpl(appWidgetId, provider);
+        bindAppWidgetIdImpl(appWidgetId, provider, options);
         return true;
     }
 
@@ -873,15 +886,18 @@
             if (id == null) {
                 return;
             }
+
             Provider p = id.provider;
-            id.options = options;
+            // Merge the options
+            id.options.putAll(options);
 
             // send the broacast saying that this appWidgetId has been deleted
             Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED);
             intent.setComponent(p.info.provider);
             intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId);
-            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
+            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, id.options);
             mContext.sendBroadcastAsUser(intent, new UserHandle(mUserId));
+            saveStateLocked();
         }
     }
 
@@ -1325,6 +1341,8 @@
                     com.android.internal.R.styleable.AppWidgetProviderInfo_updatePeriodMillis, 0);
             info.initialLayout = sa.getResourceId(
                     com.android.internal.R.styleable.AppWidgetProviderInfo_initialLayout, 0);
+            info.initialKeyguardLayout = sa.getResourceId(com.android.internal.R.styleable.
+                    AppWidgetProviderInfo_initialKeyguardLayout, 0);
             String className = sa
                     .getString(com.android.internal.R.styleable.AppWidgetProviderInfo_configure);
             if (className != null) {
@@ -1339,6 +1357,12 @@
             info.resizeMode = sa.getInt(
                     com.android.internal.R.styleable.AppWidgetProviderInfo_resizeMode,
                     AppWidgetProviderInfo.RESIZE_NONE);
+            info.widgetCategory = sa.getInt(
+                    com.android.internal.R.styleable.AppWidgetProviderInfo_resizeMode,
+                    AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
+            info.widgetFeatures = sa.getInt(
+                    com.android.internal.R.styleable.AppWidgetProviderInfo_resizeMode,
+                    AppWidgetProviderInfo.WIDGET_FEATURES_NONE);
 
             sa.recycle();
         } catch (Exception e) {
@@ -1476,6 +1500,18 @@
                 if (id.provider != null) {
                     out.attribute(null, "p", Integer.toHexString(id.provider.tag));
                 }
+                if (id.options != null) {
+                    out.attribute(null, "min_width", Integer.toHexString(id.options.getInt(
+                            AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)));
+                    out.attribute(null, "min_height", Integer.toHexString(id.options.getInt(
+                            AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)));
+                    out.attribute(null, "max_width", Integer.toHexString(id.options.getInt(
+                            AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)));
+                    out.attribute(null, "max_height", Integer.toHexString(id.options.getInt(
+                            AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)));
+                    out.attribute(null, "host_category", Integer.toHexString(id.options.getInt(
+                            AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)));
+                }
                 out.endTag(null, "g");
             }
 
@@ -1496,6 +1532,7 @@
         }
     }
 
+    @SuppressWarnings("unused")
     void readStateFromFileLocked(FileInputStream stream) {
         boolean success = false;
         try {
@@ -1569,6 +1606,34 @@
                             mNextAppWidgetId = id.appWidgetId + 1;
                         }
 
+                        Bundle options = new Bundle();
+                        String minWidthString = parser.getAttributeValue(null, "min_width");
+                        if (minWidthString != null) {
+                            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH,
+                                    Integer.parseInt(minWidthString, 16));
+                        }
+                        String minHeightString = parser.getAttributeValue(null, "min_height");
+                        if (minWidthString != null) {
+                            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT,
+                                    Integer.parseInt(minHeightString, 16));
+                        }
+                        String maxWidthString = parser.getAttributeValue(null, "max_height");
+                        if (minWidthString != null) {
+                            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH,
+                                    Integer.parseInt(maxWidthString, 16));
+                        }
+                        String maxHeightString = parser.getAttributeValue(null, "max_height");
+                        if (minWidthString != null) {
+                            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT,
+                                    Integer.parseInt(maxHeightString, 16));
+                        }
+                        String categoryString = parser.getAttributeValue(null, "host_category");
+                        if (minWidthString != null) {
+                            options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+                                    Integer.parseInt(categoryString, 16));
+                        }
+                        id.options = options;
+
                         String providerString = parser.getAttributeValue(null, "p");
                         if (providerString != null) {
                             // there's no provider if it hasn't been bound yet.
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 1d40f4f..5e2b425 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -67,6 +67,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.os.Environment.UserEnvironment;
 import android.os.storage.IMountService;
 import android.provider.Settings;
 import android.util.EventLog;
@@ -2720,9 +2721,13 @@
             FullBackup.backupToTar(pkg.packageName, FullBackup.APK_TREE_TOKEN, null,
                     apkDir, appSourceDir, output);
 
+            // TODO: migrate this to SharedStorageBackup, since AID_SYSTEM
+            // doesn't have access to external storage.
+
             // Save associated .obb content if it exists and we did save the apk
             // check for .obb and save those too
-            final File obbDir = Environment.getExternalStorageAppObbDirectory(pkg.packageName);
+            final UserEnvironment userEnv = new UserEnvironment(UserHandle.USER_OWNER);
+            final File obbDir = userEnv.getExternalStorageAppObbDirectory(pkg.packageName);
             if (obbDir != null) {
                 if (MORE_DEBUG) Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
                 File[] obbFiles = obbDir.listFiles();
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index 9404dce..e68686d 100755
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -75,12 +75,12 @@
 
     private void registerForAirplaneMode(IntentFilter filter) {
         final ContentResolver resolver = mContext.getContentResolver();
-        final String airplaneModeRadios = Settings.System.getString(resolver,
-                Settings.System.AIRPLANE_MODE_RADIOS);
-        final String toggleableRadios = Settings.System.getString(resolver,
-                Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
+        final String airplaneModeRadios = Settings.Global.getString(resolver,
+                Settings.Global.AIRPLANE_MODE_RADIOS);
+        final String toggleableRadios = Settings.Global.getString(resolver,
+                Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
         boolean mIsAirplaneSensitive = airplaneModeRadios == null ? true :
-                airplaneModeRadios.contains(Settings.System.RADIO_BLUETOOTH);
+                airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH);
         if (mIsAirplaneSensitive) {
             filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         }
@@ -151,8 +151,8 @@
      *  Returns true if airplane mode is currently on
      */
     private final boolean isAirplaneModeOn() {
-        return Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
     }
 
     /**
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index f40333d..32ab154 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -16,11 +16,7 @@
 
 package com.android.server;
 
-import com.android.internal.app.IMediaContainerService;
-import com.android.internal.util.XmlUtils;
-import com.android.server.am.ActivityManagerService;
-import com.android.server.pm.PackageManagerService;
-import com.android.server.NativeDaemonConnector.Command;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import android.Manifest;
 import android.content.BroadcastReceiver;
@@ -30,6 +26,7 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
 import android.content.res.ObbInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -38,15 +35,14 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Environment;
+import android.os.Environment.UserEnvironment;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.storage.IMountService;
@@ -61,9 +57,18 @@
 import android.util.Slog;
 import android.util.Xml;
 
-import org.xmlpull.v1.XmlPullParser;
+import com.android.internal.app.IMediaContainerService;
+import com.android.internal.util.XmlUtils;
+import com.android.server.NativeDaemonConnector.Command;
+import com.android.server.am.ActivityManagerService;
+import com.android.server.pm.PackageManagerService;
+import com.android.server.pm.UserManagerService;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+
 import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -81,7 +86,6 @@
 import java.util.Map.Entry;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import java.util.Set;
 
 import javax.crypto.SecretKey;
 import javax.crypto.SecretKeyFactory;
@@ -96,9 +100,11 @@
 class MountService extends IMountService.Stub
         implements INativeDaemonConnectorCallbacks, Watchdog.Monitor {
 
-    private static final boolean LOCAL_LOGD = false;
-    private static final boolean DEBUG_UNMOUNT = false;
-    private static final boolean DEBUG_EVENTS = false;
+    // TODO: listen for user creation/deletion
+
+    private static final boolean LOCAL_LOGD = true;
+    private static final boolean DEBUG_UNMOUNT = true;
+    private static final boolean DEBUG_EVENTS = true;
     private static final boolean DEBUG_OBB = false;
 
     // Disable this since it messes up long-running cryptfs operations.
@@ -166,25 +172,34 @@
         public static final int VolumeBadRemoval               = 632;
     }
 
-    private Context                               mContext;
-    private NativeDaemonConnector                 mConnector;
-    private final ArrayList<StorageVolume>        mVolumes = new ArrayList<StorageVolume>();
-    private StorageVolume                         mPrimaryVolume;
-    private final HashMap<String, String>         mVolumeStates = new HashMap<String, String>();
-    private final HashMap<String, StorageVolume>  mVolumeMap = new HashMap<String, StorageVolume>();
-    private String                                mExternalStoragePath;
+    private Context mContext;
+    private NativeDaemonConnector mConnector;
+
+    private final Object mVolumesLock = new Object();
+
+    /** When defined, base template for user-specific {@link StorageVolume}. */
+    private StorageVolume mEmulatedTemplate;
+
+    // @GuardedBy("mVolumesLock")
+    private final ArrayList<StorageVolume> mVolumes = Lists.newArrayList();
+    /** Map from path to {@link StorageVolume} */
+    // @GuardedBy("mVolumesLock")
+    private final HashMap<String, StorageVolume> mVolumesByPath = Maps.newHashMap();
+    /** Map from path to state */
+    // @GuardedBy("mVolumesLock")
+    private final HashMap<String, String> mVolumeStates = Maps.newHashMap();
+
+    private volatile boolean mSystemReady = false;
+
     private PackageManagerService                 mPms;
     private boolean                               mUmsEnabling;
     private boolean                               mUmsAvailable = false;
     // Used as a lock for methods that register/unregister listeners.
     final private ArrayList<MountServiceBinderListener> mListeners =
             new ArrayList<MountServiceBinderListener>();
-    private boolean                               mBooted = false;
     private CountDownLatch                        mConnectedSignal = new CountDownLatch(1);
     private CountDownLatch                        mAsecsScanned = new CountDownLatch(1);
     private boolean                               mSendUmsConnectedOnBoot = false;
-    // true if we should fake MEDIA_MOUNTED state for external storage
-    private boolean                               mEmulateExternalStorage = false;
 
     /**
      * Private hash of currently mounted secure containers.
@@ -303,6 +318,8 @@
     private static final int H_UNMOUNT_PM_UPDATE = 1;
     private static final int H_UNMOUNT_PM_DONE = 2;
     private static final int H_UNMOUNT_MS = 3;
+    private static final int H_SYSTEM_READY = 4;
+
     private static final int RETRY_UNMOUNT_DELAY = 30; // in ms
     private static final int MAX_UNMOUNT_RETRIES = 4;
 
@@ -437,17 +454,26 @@
                     }
                     break;
                 }
-                case H_UNMOUNT_MS : {
+                case H_UNMOUNT_MS: {
                     if (DEBUG_UNMOUNT) Slog.i(TAG, "H_UNMOUNT_MS");
                     UnmountCallBack ucb = (UnmountCallBack) msg.obj;
                     ucb.handleFinished();
                     break;
                 }
+                case H_SYSTEM_READY: {
+                    try {
+                        handleSystemReady();
+                    } catch (Exception ex) {
+                        Slog.e(TAG, "Boot-time mount exception", ex);
+                    }
+                    break;
+                }
             }
         }
     };
-    final private HandlerThread mHandlerThread;
-    final private Handler mHandler;
+
+    private final HandlerThread mHandlerThread;
+    private final Handler mHandler;
 
     void waitForAsecScan() {
         waitForLatch(mAsecsScanned);
@@ -476,90 +502,119 @@
         }
     }
 
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+    private void handleSystemReady() {
+        // Snapshot current volume states since it's not safe to call into vold
+        // while holding locks.
+        final HashMap<String, String> snapshot;
+        synchronized (mVolumesLock) {
+            snapshot = new HashMap<String, String>(mVolumeStates);
+        }
+
+        for (Map.Entry<String, String> entry : snapshot.entrySet()) {
+            final String path = entry.getKey();
+            final String state = entry.getValue();
+
+            if (state.equals(Environment.MEDIA_UNMOUNTED)) {
+                int rc = doMountVolume(path);
+                if (rc != StorageResultCode.OperationSucceeded) {
+                    Slog.e(TAG, String.format("Boot-time mount failed (%d)",
+                            rc));
+                }
+            } else if (state.equals(Environment.MEDIA_SHARED)) {
+                /*
+                 * Bootstrap UMS enabled state since vold indicates
+                 * the volume is shared (runtime restart while ums enabled)
+                 */
+                notifyVolumeStateChange(null, path, VolumeState.NoMedia,
+                        VolumeState.Shared);
+            }
+        }
+
+        // Push mounted state for all emulated storage
+        synchronized (mVolumesLock) {
+            for (StorageVolume volume : mVolumes) {
+                if (volume.isEmulated()) {
+                    updatePublicVolumeState(volume, Environment.MEDIA_MOUNTED);
+                }
+            }
+        }
+
+        /*
+         * If UMS was connected on boot, send the connected event
+         * now that we're up.
+         */
+        if (mSendUmsConnectedOnBoot) {
+            sendUmsIntent(true);
+            mSendUmsConnectedOnBoot = false;
+        }
+    }
+
+    private final BroadcastReceiver mBootReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
+            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+            if (userId == -1) return;
+            final UserHandle user = new UserHandle(userId);
 
-            if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
-                mBooted = true;
+            Slog.d(TAG, "BOOT_COMPLETED for " + user);
 
-                /*
-                 * In the simulator, we need to broadcast a volume mounted event
-                 * to make the media scanner run.
-                 */
-                if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
-                    notifyVolumeStateChange(null, "/sdcard", VolumeState.NoMedia,
-                            VolumeState.Mounted);
-                    return;
-                }
-                new Thread() {
-                    @Override
-                    public void run() {
-                        try {
-                            // it is not safe to call vold with mVolumeStates locked
-                            // so we make a copy of the paths and states and process them
-                            // outside the lock
-                            String[] paths;
-                            String[] states;
-                            int count;
-                            synchronized (mVolumeStates) {
-                                Set<String> keys = mVolumeStates.keySet();
-                                count = keys.size();
-                                paths = keys.toArray(new String[count]);
-                                states = new String[count];
-                                for (int i = 0; i < count; i++) {
-                                    states[i] = mVolumeStates.get(paths[i]);
-                                }
-                            }
+            // Broadcast mounted volumes to newly booted user. This kicks off
+            // media scanner when a user becomes active.
+            synchronized (mVolumesLock) {
+                for (StorageVolume volume : mVolumes) {
+                    final UserHandle owner = volume.getOwner();
+                    final boolean ownerMatch = owner == null
+                            || owner.getIdentifier() == user.getIdentifier();
 
-                            for (int i = 0; i < count; i++) {
-                                String path = paths[i];
-                                String state = states[i];
+                    final String state = mVolumeStates.get(volume.getPath());
 
-                                if (state.equals(Environment.MEDIA_UNMOUNTED)) {
-                                    int rc = doMountVolume(path);
-                                    if (rc != StorageResultCode.OperationSucceeded) {
-                                        Slog.e(TAG, String.format("Boot-time mount failed (%d)",
-                                                rc));
-                                    }
-                                } else if (state.equals(Environment.MEDIA_SHARED)) {
-                                    /*
-                                     * Bootstrap UMS enabled state since vold indicates
-                                     * the volume is shared (runtime restart while ums enabled)
-                                     */
-                                    notifyVolumeStateChange(null, path, VolumeState.NoMedia,
-                                            VolumeState.Shared);
-                                }
-                            }
-
-                            /* notify external storage has mounted to trigger media scanner */
-                            if (mEmulateExternalStorage) {
-                                notifyVolumeStateChange(null,
-                                        Environment.getExternalStorageDirectory().getPath(),
-                                        VolumeState.NoMedia, VolumeState.Mounted);
-                            }
-
-                            /*
-                             * If UMS was connected on boot, send the connected event
-                             * now that we're up.
-                             */
-                            if (mSendUmsConnectedOnBoot) {
-                                sendUmsIntent(true);
-                                mSendUmsConnectedOnBoot = false;
-                            }
-                        } catch (Exception ex) {
-                            Slog.e(TAG, "Boot-time mount exception", ex);
-                        }
+                    if (ownerMatch && (Environment.MEDIA_MOUNTED.equals(state)
+                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state))) {
+                        sendStorageIntent(Intent.ACTION_MEDIA_MOUNTED, volume, user);
                     }
-                }.start();
-            } else if (action.equals(UsbManager.ACTION_USB_STATE)) {
-                boolean available = (intent.getBooleanExtra(UsbManager.USB_CONNECTED, false) &&
-                        intent.getBooleanExtra(UsbManager.USB_FUNCTION_MASS_STORAGE, false));
-                notifyShareAvailabilityChange(available);
+                }
             }
         }
     };
+
+    private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+            if (userId == -1) return;
+            final UserHandle user = new UserHandle(userId);
+
+            final String action = intent.getAction();
+            if (Intent.ACTION_USER_ADDED.equals(action)) {
+                synchronized (mVolumesLock) {
+                    createEmulatedVolumeForUserLocked(user);
+                }
+
+            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+                synchronized (mVolumesLock) {
+                    final List<StorageVolume> toRemove = Lists.newArrayList();
+                    for (StorageVolume volume : mVolumes) {
+                        if (user.equals(volume.getOwner())) {
+                            toRemove.add(volume);
+                        }
+                    }
+                    for (StorageVolume volume : toRemove) {
+                        removeVolumeLocked(volume);
+                    }
+                }
+            }
+        }
+    };
+
+    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            boolean available = (intent.getBooleanExtra(UsbManager.USB_CONNECTED, false) &&
+                    intent.getBooleanExtra(UsbManager.USB_FUNCTION_MASS_STORAGE, false));
+            notifyShareAvailabilityChange(available);
+        }
+    };
+
     private final class MountServiceBinderListener implements IBinder.DeathRecipient {
         final IMountServiceListener mListener;
 
@@ -590,11 +645,13 @@
         }
     }
 
-    private void updatePublicVolumeState(String path, String state) {
-        String oldState;
-        synchronized(mVolumeStates) {
+    private void updatePublicVolumeState(StorageVolume volume, String state) {
+        final String path = volume.getPath();
+        final String oldState;
+        synchronized (mVolumesLock) {
             oldState = mVolumeStates.put(path, state);
         }
+
         if (state.equals(oldState)) {
             Slog.w(TAG, String.format("Duplicate state transition (%s -> %s) for %s",
                     state, state, path));
@@ -603,24 +660,24 @@
 
         Slog.d(TAG, "volume state changed for " + path + " (" + oldState + " -> " + state + ")");
 
-        if (path.equals(mExternalStoragePath)) {
-            // Update state on PackageManager, but only of real events
-            if (!mEmulateExternalStorage) {
-                if (Environment.MEDIA_UNMOUNTED.equals(state)) {
-                    mPms.updateExternalMediaStatus(false, false);
+        // Tell PackageManager about changes to primary volume state, but only
+        // when not emulated.
+        if (volume.isPrimary() && !volume.isEmulated()) {
+            if (Environment.MEDIA_UNMOUNTED.equals(state)) {
+                mPms.updateExternalMediaStatus(false, false);
 
-                    /*
-                     * Some OBBs might have been unmounted when this volume was
-                     * unmounted, so send a message to the handler to let it know to
-                     * remove those from the list of mounted OBBS.
-                     */
-                    mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(
-                            OBB_FLUSH_MOUNT_STATE, path));
-                } else if (Environment.MEDIA_MOUNTED.equals(state)) {
-                    mPms.updateExternalMediaStatus(true, false);
-                }
+                /*
+                 * Some OBBs might have been unmounted when this volume was
+                 * unmounted, so send a message to the handler to let it know to
+                 * remove those from the list of mounted OBBS.
+                 */
+                mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(
+                        OBB_FLUSH_MOUNT_STATE, path));
+            } else if (Environment.MEDIA_MOUNTED.equals(state)) {
+                mPms.updateExternalMediaStatus(true, false);
             }
         }
+
         synchronized (mListeners) {
             for (int i = mListeners.size() -1; i >= 0; i--) {
                 MountServiceBinderListener bl = mListeners.get(i);
@@ -637,7 +694,6 @@
     }
 
     /**
-     *
      * Callback from NativeDaemonConnector
      */
     public void onDaemonConnected() {
@@ -661,6 +717,11 @@
                         String path = tok[1];
                         String state = Environment.MEDIA_REMOVED;
 
+                        final StorageVolume volume;
+                        synchronized (mVolumesLock) {
+                            volume = mVolumesByPath.get(path);
+                        }
+
                         int st = Integer.parseInt(tok[2]);
                         if (st == VolumeState.NoMedia) {
                             state = Environment.MEDIA_REMOVED;
@@ -678,12 +739,15 @@
 
                         if (state != null) {
                             if (DEBUG_EVENTS) Slog.i(TAG, "Updating valid state " + state);
-                            updatePublicVolumeState(path, state);
+                            updatePublicVolumeState(volume, state);
                         }
                     }
                 } catch (Exception e) {
                     Slog.e(TAG, "Error processing initial volume state", e);
-                    updatePublicVolumeState(mExternalStoragePath, Environment.MEDIA_REMOVED);
+                    final StorageVolume primary = getPrimaryPhysicalVolume();
+                    if (primary != null) {
+                        updatePublicVolumeState(primary, Environment.MEDIA_REMOVED);
+                    }
                 }
 
                 /*
@@ -749,6 +813,13 @@
                 Slog.e(TAG, "Failed to parse major/minor", ex);
             }
 
+            final StorageVolume volume;
+            final String state;
+            synchronized (mVolumesLock) {
+                volume = mVolumesByPath.get(path);
+                state = mVolumeStates.get(path);
+            }
+
             if (code == VoldResponseCode.VolumeDiskInserted) {
                 new Thread() {
                     @Override
@@ -772,27 +843,27 @@
                 }
                 /* Send the media unmounted event first */
                 if (DEBUG_EVENTS) Slog.i(TAG, "Sending unmounted event first");
-                updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
-                sendStorageIntent(Environment.MEDIA_UNMOUNTED, path);
+                updatePublicVolumeState(volume, Environment.MEDIA_UNMOUNTED);
+                sendStorageIntent(Environment.MEDIA_UNMOUNTED, volume, UserHandle.ALL);
 
                 if (DEBUG_EVENTS) Slog.i(TAG, "Sending media removed");
-                updatePublicVolumeState(path, Environment.MEDIA_REMOVED);
+                updatePublicVolumeState(volume, Environment.MEDIA_REMOVED);
                 action = Intent.ACTION_MEDIA_REMOVED;
             } else if (code == VoldResponseCode.VolumeBadRemoval) {
                 if (DEBUG_EVENTS) Slog.i(TAG, "Sending unmounted event first");
                 /* Send the media unmounted event first */
-                updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
+                updatePublicVolumeState(volume, Environment.MEDIA_UNMOUNTED);
                 action = Intent.ACTION_MEDIA_UNMOUNTED;
 
                 if (DEBUG_EVENTS) Slog.i(TAG, "Sending media bad removal");
-                updatePublicVolumeState(path, Environment.MEDIA_BAD_REMOVAL);
+                updatePublicVolumeState(volume, Environment.MEDIA_BAD_REMOVAL);
                 action = Intent.ACTION_MEDIA_BAD_REMOVAL;
             } else {
                 Slog.e(TAG, String.format("Unknown code {%d}", code));
             }
 
             if (action != null) {
-                sendStorageIntent(action, path);
+                sendStorageIntent(action, volume, UserHandle.ALL);
             }
         } else {
             return false;
@@ -802,14 +873,20 @@
     }
 
     private void notifyVolumeStateChange(String label, String path, int oldState, int newState) {
-        String vs = getVolumeState(path);
-        if (DEBUG_EVENTS) Slog.i(TAG, "notifyVolumeStateChanged::" + vs);
+        final StorageVolume volume;
+        final String state;
+        synchronized (mVolumesLock) {
+            volume = mVolumesByPath.get(path);
+            state = getVolumeState(path);
+        }
+
+        if (DEBUG_EVENTS) Slog.i(TAG, "notifyVolumeStateChange::" + state);
 
         String action = null;
 
         if (oldState == VolumeState.Shared && newState != oldState) {
             if (LOCAL_LOGD) Slog.d(TAG, "Sending ACTION_MEDIA_UNSHARED intent");
-            sendStorageIntent(Intent.ACTION_MEDIA_UNSHARED,  path);
+            sendStorageIntent(Intent.ACTION_MEDIA_UNSHARED, volume, UserHandle.ALL);
         }
 
         if (newState == VolumeState.Init) {
@@ -820,22 +897,22 @@
              * Don't notify if we're in BAD_REMOVAL, NOFS, UNMOUNTABLE, or
              * if we're in the process of enabling UMS
              */
-            if (!vs.equals(
-                    Environment.MEDIA_BAD_REMOVAL) && !vs.equals(
-                            Environment.MEDIA_NOFS) && !vs.equals(
+            if (!state.equals(
+                    Environment.MEDIA_BAD_REMOVAL) && !state.equals(
+                            Environment.MEDIA_NOFS) && !state.equals(
                                     Environment.MEDIA_UNMOUNTABLE) && !getUmsEnabling()) {
                 if (DEBUG_EVENTS) Slog.i(TAG, "updating volume state for media bad removal nofs and unmountable");
-                updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
+                updatePublicVolumeState(volume, Environment.MEDIA_UNMOUNTED);
                 action = Intent.ACTION_MEDIA_UNMOUNTED;
             }
         } else if (newState == VolumeState.Pending) {
         } else if (newState == VolumeState.Checking) {
             if (DEBUG_EVENTS) Slog.i(TAG, "updating volume state checking");
-            updatePublicVolumeState(path, Environment.MEDIA_CHECKING);
+            updatePublicVolumeState(volume, Environment.MEDIA_CHECKING);
             action = Intent.ACTION_MEDIA_CHECKING;
         } else if (newState == VolumeState.Mounted) {
             if (DEBUG_EVENTS) Slog.i(TAG, "updating volume state mounted");
-            updatePublicVolumeState(path, Environment.MEDIA_MOUNTED);
+            updatePublicVolumeState(volume, Environment.MEDIA_MOUNTED);
             action = Intent.ACTION_MEDIA_MOUNTED;
         } else if (newState == VolumeState.Unmounting) {
             action = Intent.ACTION_MEDIA_EJECT;
@@ -843,11 +920,11 @@
         } else if (newState == VolumeState.Shared) {
             if (DEBUG_EVENTS) Slog.i(TAG, "Updating volume state media mounted");
             /* Send the media unmounted event first */
-            updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
-            sendStorageIntent(Intent.ACTION_MEDIA_UNMOUNTED, path);
+            updatePublicVolumeState(volume, Environment.MEDIA_UNMOUNTED);
+            sendStorageIntent(Intent.ACTION_MEDIA_UNMOUNTED, volume, UserHandle.ALL);
 
             if (DEBUG_EVENTS) Slog.i(TAG, "Updating media shared");
-            updatePublicVolumeState(path, Environment.MEDIA_SHARED);
+            updatePublicVolumeState(volume, Environment.MEDIA_SHARED);
             action = Intent.ACTION_MEDIA_SHARED;
             if (LOCAL_LOGD) Slog.d(TAG, "Sending ACTION_MEDIA_SHARED intent");
         } else if (newState == VolumeState.SharedMnt) {
@@ -858,13 +935,18 @@
         }
 
         if (action != null) {
-            sendStorageIntent(action, path);
+            sendStorageIntent(action, volume, UserHandle.ALL);
         }
     }
 
     private int doMountVolume(String path) {
         int rc = StorageResultCode.OperationSucceeded;
 
+        final StorageVolume volume;
+        synchronized (mVolumesLock) {
+            volume = mVolumesByPath.get(path);
+        }
+
         if (DEBUG_EVENTS) Slog.i(TAG, "doMountVolume: Mouting " + path);
         try {
             mConnector.execute("volume", "mount", path);
@@ -884,7 +966,7 @@
                 /*
                  * Media is blank or does not contain a supported filesystem
                  */
-                updatePublicVolumeState(path, Environment.MEDIA_NOFS);
+                updatePublicVolumeState(volume, Environment.MEDIA_NOFS);
                 action = Intent.ACTION_MEDIA_NOFS;
                 rc = StorageResultCode.OperationFailedMediaBlank;
             } else if (code == VoldResponseCode.OpFailedMediaCorrupt) {
@@ -892,7 +974,7 @@
                 /*
                  * Volume consistency check failed
                  */
-                updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTABLE);
+                updatePublicVolumeState(volume, Environment.MEDIA_UNMOUNTABLE);
                 action = Intent.ACTION_MEDIA_UNMOUNTABLE;
                 rc = StorageResultCode.OperationFailedMediaCorrupt;
             } else {
@@ -903,7 +985,7 @@
              * Send broadcast intent (if required for the failure)
              */
             if (action != null) {
-                sendStorageIntent(action, path);
+                sendStorageIntent(action, volume, UserHandle.ALL);
             }
         }
 
@@ -1011,14 +1093,16 @@
             }
         }
 
-        if (mBooted == true) {
+        if (mSystemReady == true) {
             sendUmsIntent(avail);
         } else {
             mSendUmsConnectedOnBoot = avail;
         }
 
-        final String path = Environment.getExternalStorageDirectory().getPath();
-        if (avail == false && getVolumeState(path).equals(Environment.MEDIA_SHARED)) {
+        final StorageVolume primary = getPrimaryPhysicalVolume();
+        if (avail == false && primary != null
+                && Environment.MEDIA_SHARED.equals(getVolumeState(primary.getPath()))) {
+            final String path = primary.getPath();
             /*
              * USB mass storage disconnected while enabled
              */
@@ -1042,12 +1126,11 @@
         }
     }
 
-    private void sendStorageIntent(String action, String path) {
-        Intent intent = new Intent(action, Uri.parse("file://" + path));
-        // add StorageVolume extra
-        intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, mVolumeMap.get(path));
-        Slog.d(TAG, "sendStorageIntent " + intent);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+    private void sendStorageIntent(String action, StorageVolume volume, UserHandle user) {
+        final Intent intent = new Intent(action, Uri.parse("file://" + volume.getPath()));
+        intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, volume);
+        Slog.d(TAG, "sendStorageIntent " + intent + " to " + user);
+        mContext.sendBroadcastAsUser(intent, user);
     }
 
     private void sendUmsIntent(boolean c) {
@@ -1066,7 +1149,10 @@
     private static final String TAG_STORAGE_LIST = "StorageList";
     private static final String TAG_STORAGE = "storage";
 
-    private void readStorageList() {
+    private void readStorageListLocked() {
+        mVolumes.clear();
+        mVolumeStates.clear();
+
         Resources resources = mContext.getResources();
 
         int id = com.android.internal.R.xml.storage_list;
@@ -1085,7 +1171,7 @@
                     TypedArray a = resources.obtainAttributes(attrs,
                             com.android.internal.R.styleable.Storage);
 
-                    CharSequence path = a.getText(
+                    String path = a.getString(
                             com.android.internal.R.styleable.Storage_mountPoint);
                     int descriptionId = a.getResourceId(
                             com.android.internal.R.styleable.Storage_storageDescription, -1);
@@ -1110,27 +1196,29 @@
                             " emulated: " + emulated +  " mtpReserve: " + mtpReserve +
                             " allowMassStorage: " + allowMassStorage +
                             " maxFileSize: " + maxFileSize);
-                    if (path == null || description == null) {
-                        Slog.e(TAG, "path or description is null in readStorageList");
+
+                    if (emulated) {
+                        // For devices with emulated storage, we create separate
+                        // volumes for each known user.
+                        mEmulatedTemplate = new StorageVolume(null, descriptionId, true, false,
+                                true, mtpReserve, false, maxFileSize, null);
+
+                        final UserManagerService userManager = UserManagerService.getInstance();
+                        for (UserInfo user : userManager.getUsers()) {
+                            createEmulatedVolumeForUserLocked(user.getUserHandle());
+                        }
+
                     } else {
-                        String pathString = path.toString();
-                        StorageVolume volume = new StorageVolume(pathString, descriptionId, primary,
-                                removable, emulated, mtpReserve, allowMassStorage, maxFileSize);
-                        if (primary) {
-                            if (mPrimaryVolume == null) {
-                                mPrimaryVolume = volume;
-                            } else {
-                                Slog.e(TAG, "multiple primary volumes in storage list");
-                            }
-                        }
-                        if (mPrimaryVolume == volume) {
-                            // primay volume must be first
-                            mVolumes.add(0, volume);
+                        if (path == null || description == null) {
+                            Slog.e(TAG, "Missing storage path or description in readStorageList");
                         } else {
-                            mVolumes.add(volume);
+                            final StorageVolume volume = new StorageVolume(new File(path),
+                                    descriptionId, primary, removable, emulated, mtpReserve,
+                                    allowMassStorage, maxFileSize, null);
+                            addVolumeLocked(volume);
                         }
-                        mVolumeMap.put(pathString, volume);
                     }
+
                     a.recycle();
                 }
             }
@@ -1139,48 +1227,105 @@
         } catch (IOException e) {
             throw new RuntimeException(e);
         } finally {
-            // compute storage ID for each volume
-            int length = mVolumes.size();
-            for (int i = 0; i < length; i++) {
-                mVolumes.get(i).setStorageId(i);
+            // Compute storage ID for each physical volume; emulated storage is
+            // always 0 when defined.
+            int index = isExternalStorageEmulated() ? 1 : 0;
+            for (StorageVolume volume : mVolumes) {
+                if (!volume.isEmulated()) {
+                    volume.setStorageId(index++);
+                }
             }
             parser.close();
         }
     }
 
     /**
+     * Create and add new {@link StorageVolume} for given {@link UserHandle}
+     * using {@link #mEmulatedTemplate} as template.
+     */
+    private void createEmulatedVolumeForUserLocked(UserHandle user) {
+        if (mEmulatedTemplate == null) {
+            throw new IllegalStateException("Missing emulated volume multi-user template");
+        }
+
+        final UserEnvironment userEnv = new UserEnvironment(user.getIdentifier());
+        final File path = userEnv.getExternalStorageDirectory();
+        final StorageVolume volume = StorageVolume.fromTemplate(mEmulatedTemplate, path, user);
+        volume.setStorageId(0);
+        addVolumeLocked(volume);
+
+        if (mSystemReady) {
+            updatePublicVolumeState(volume, Environment.MEDIA_MOUNTED);
+        } else {
+            // Place stub status for early callers to find
+            mVolumeStates.put(volume.getPath(), Environment.MEDIA_MOUNTED);
+        }
+    }
+
+    private void addVolumeLocked(StorageVolume volume) {
+        Slog.d(TAG, "addVolumeLocked() " + volume);
+        mVolumes.add(volume);
+        final StorageVolume existing = mVolumesByPath.put(volume.getPath(), volume);
+        if (existing != null) {
+            throw new IllegalStateException(
+                    "Volume at " + volume.getPath() + " already exists: " + existing);
+        }
+    }
+
+    private void removeVolumeLocked(StorageVolume volume) {
+        Slog.d(TAG, "removeVolumeLocked() " + volume);
+        mVolumes.remove(volume);
+        mVolumesByPath.remove(volume.getPath());
+        mVolumeStates.remove(volume.getPath());
+    }
+
+    private StorageVolume getPrimaryPhysicalVolume() {
+        synchronized (mVolumesLock) {
+            for (StorageVolume volume : mVolumes) {
+                if (volume.isPrimary() && !volume.isEmulated()) {
+                    return volume;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * Constructs a new MountService instance
      *
      * @param context  Binder context for this service
      */
     public MountService(Context context) {
         mContext = context;
-        readStorageList();
 
-        if (mPrimaryVolume != null) {
-            mExternalStoragePath = mPrimaryVolume.getPath();
-            mEmulateExternalStorage = mPrimaryVolume.isEmulated();
-            if (mEmulateExternalStorage) {
-                Slog.d(TAG, "using emulated external storage");
-                mVolumeStates.put(mExternalStoragePath, Environment.MEDIA_MOUNTED);
-            }
+        synchronized (mVolumesLock) {
+            readStorageListLocked();
         }
 
         // XXX: This will go away soon in favor of IMountServiceObserver
         mPms = (PackageManagerService) ServiceManager.getService("package");
 
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_BOOT_COMPLETED);
-        // don't bother monitoring USB if mass storage is not supported on our primary volume
-        if (mPrimaryVolume != null && mPrimaryVolume.allowMassStorage()) {
-            filter.addAction(UsbManager.ACTION_USB_STATE);
-        }
-        mContext.registerReceiver(mBroadcastReceiver, filter, null, null);
-
         mHandlerThread = new HandlerThread("MountService");
         mHandlerThread.start();
         mHandler = new MountServiceHandler(mHandlerThread.getLooper());
 
+        // Watch for user boot completion
+        mContext.registerReceiverAsUser(mBootReceiver, UserHandle.ALL,
+                new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, mHandler);
+
+        // Watch for user changes
+        final IntentFilter userFilter = new IntentFilter();
+        userFilter.addAction(Intent.ACTION_USER_ADDED);
+        userFilter.addAction(Intent.ACTION_USER_REMOVED);
+        mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
+
+        // Watch for USB changes on primary volume
+        final StorageVolume primary = getPrimaryPhysicalVolume();
+        if (primary != null && primary.allowMassStorage()) {
+            mContext.registerReceiver(
+                    mUsbReceiver, new IntentFilter(UsbManager.ACTION_USB_STATE), null, mHandler);
+        }
+
         // Add OBB Action Handler to MountService thread.
         mObbActionHandler = new ObbActionHandler(mHandlerThread.getLooper());
 
@@ -1200,6 +1345,11 @@
         }
     }
 
+    public void systemReady() {
+        mSystemReady = true;
+        mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
+    }
+
     /**
      * Exposed API calls below here
      */
@@ -1232,7 +1382,7 @@
         validatePermission(android.Manifest.permission.SHUTDOWN);
 
         Slog.i(TAG, "Shutting down");
-        synchronized (mVolumeStates) {
+        synchronized (mVolumesLock) {
             for (String path : mVolumeStates.keySet()) {
                 String state = mVolumeStates.get(path);
 
@@ -1313,12 +1463,15 @@
         waitForReady();
         validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
+        final StorageVolume primary = getPrimaryPhysicalVolume();
+        if (primary == null) return;
+
         // TODO: Add support for multiple share methods
 
         /*
          * If the volume is mounted and we're enabling then unmount it
          */
-        String path = Environment.getExternalStorageDirectory().getPath();
+        String path = primary.getPath();
         String vs = getVolumeState(path);
         String method = "ums";
         if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
@@ -1348,14 +1501,20 @@
 
     public boolean isUsbMassStorageEnabled() {
         waitForReady();
-        return doGetVolumeShared(Environment.getExternalStorageDirectory().getPath(), "ums");
+
+        final StorageVolume primary = getPrimaryPhysicalVolume();
+        if (primary != null) {
+            return doGetVolumeShared(primary.getPath(), "ums");
+        } else {
+            return false;
+        }
     }
 
     /**
      * @return state of the volume at the specified mount point
      */
     public String getVolumeState(String mountPoint) {
-        synchronized (mVolumeStates) {
+        synchronized (mVolumesLock) {
             String state = mVolumeStates.get(mountPoint);
             if (state == null) {
                 Slog.w(TAG, "getVolumeState(" + mountPoint + "): Unknown volume");
@@ -1370,8 +1529,9 @@
         }
     }
 
+    @Override
     public boolean isExternalStorageEmulated() {
-        return mEmulateExternalStorage;
+        return mEmulatedTemplate != null;
     }
 
     public int mountVolume(String path) {
@@ -1437,7 +1597,9 @@
     }
 
     private void warnOnNotMounted() {
-        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+        final StorageVolume primary = getPrimaryPhysicalVolume();
+        if (primary != null
+                && Environment.MEDIA_MOUNTED.equals(getVolumeState(primary.getPath()))) {
             Slog.w(TAG, "getSecureContainerList() called when storage not mounted");
         }
     }
@@ -1935,14 +2097,23 @@
         }
     }
 
-    public Parcelable[] getVolumeList() {
-        synchronized(mVolumes) {
-            int size = mVolumes.size();
-            Parcelable[] result = new Parcelable[size];
-            for (int i = 0; i < size; i++) {
-                result[i] = mVolumes.get(i);
+    @Override
+    public StorageVolume[] getVolumeList() {
+        final int callingUserId = UserHandle.getCallingUserId();
+        final boolean accessAll = (mContext.checkPermission(
+                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
+                Binder.getCallingPid(), Binder.getCallingUid()) == PERMISSION_GRANTED);
+
+        synchronized (mVolumesLock) {
+            final ArrayList<StorageVolume> filtered = Lists.newArrayList();
+            for (StorageVolume volume : mVolumes) {
+                final UserHandle owner = volume.getOwner();
+                final boolean ownerMatch = owner == null || owner.getIdentifier() == callingUserId;
+                if (accessAll || ownerMatch) {
+                    filtered.add(volume);
+                }
             }
-            return result;
+            return filtered.toArray(new StorageVolume[filtered.size()]);
         }
     }
 
@@ -2458,7 +2629,7 @@
 
         pw.println("");
 
-        synchronized (mVolumes) {
+        synchronized (mVolumesLock) {
             pw.println("  mVolumes:");
 
             final int N = mVolumes.size();
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c28afb2..4398441 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -37,14 +37,12 @@
 import android.os.StrictMode;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import android.provider.Settings;
 import android.server.search.SearchManagerService;
 import android.service.dreams.DreamManagerService;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
-import android.view.Display;
 import android.view.WindowManager;
 
 import com.android.internal.os.BinderInternal;
@@ -127,6 +125,7 @@
         BatteryService battery = null;
         VibratorService vibrator = null;
         AlarmManagerService alarm = null;
+        MountService mountService = null;
         NetworkManagementService networkManagement = null;
         NetworkStatsService networkStats = null;
         NetworkPolicyManagerService networkPolicy = null;
@@ -376,7 +375,6 @@
         }
 
         if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
-            MountService mountService = null;
             if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
                 try {
                     /*
@@ -815,6 +813,7 @@
 
         // These are needed to propagate to the runnable below.
         final Context contextF = context;
+        final MountService mountServiceF = mountService;
         final BatteryService batteryF = battery;
         final NetworkManagementService networkManagementF = networkManagement;
         final NetworkStatsService networkStatsF = networkStats;
@@ -849,6 +848,11 @@
 
                 if (!headless) startSystemUi(contextF);
                 try {
+                    if (mountServiceF != null) mountServiceF.systemReady();
+                } catch (Throwable e) {
+                    reportWtf("making Mount Service ready", e);
+                }
+                try {
                     if (batteryF != null) batteryF.systemReady();
                 } catch (Throwable e) {
                     reportWtf("making Battery Service ready", e);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 6bc5e10..7ed4f8a 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1179,17 +1179,17 @@
     }
 
     private boolean isAirplaneSensitive() {
-        String airplaneModeRadios = Settings.System.getString(mContext.getContentResolver(),
-                Settings.System.AIRPLANE_MODE_RADIOS);
+        String airplaneModeRadios = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_RADIOS);
         return airplaneModeRadios == null
-            || airplaneModeRadios.contains(Settings.System.RADIO_WIFI);
+            || airplaneModeRadios.contains(Settings.Global.RADIO_WIFI);
     }
 
     private boolean isAirplaneToggleable() {
-        String toggleableRadios = Settings.System.getString(mContext.getContentResolver(),
-                Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
+        String toggleableRadios = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
         return toggleableRadios != null
-            && toggleableRadios.contains(Settings.System.RADIO_WIFI);
+            && toggleableRadios.contains(Settings.Global.RADIO_WIFI);
     }
 
     /**
@@ -1198,8 +1198,8 @@
      * @return {@code true} if airplane mode is on.
      */
     private boolean isAirplaneModeOn() {
-        return isAirplaneSensitive() && Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+        return isAirplaneSensitive() && Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
     }
 
     @Override
@@ -1213,8 +1213,8 @@
         }
         pw.println("Wi-Fi is " + mWifiStateMachine.syncGetWifiStateByName());
         pw.println("Stay-awake conditions: " +
-                Settings.System.getInt(mContext.getContentResolver(),
-                                       Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0));
+                Settings.Global.getInt(mContext.getContentResolver(),
+                                       Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0));
         pw.println();
 
         pw.println("Internal state:");
diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java
index 62d410b..48781ac 100644
--- a/services/java/com/android/server/accessibility/ScreenMagnifier.java
+++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java
@@ -21,11 +21,13 @@
 import android.animation.ObjectAnimator;
 import android.animation.TypeEvaluator;
 import android.animation.ValueAnimator;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
-import android.graphics.PointF;
 import android.graphics.PorterDuff.Mode;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -37,18 +39,20 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.Settings;
-import android.util.MathUtils;
 import android.util.Property;
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.GestureDetector;
+import android.view.GestureDetector.SimpleOnGestureListener;
 import android.view.Gravity;
 import android.view.IDisplayContentChangeListener;
 import android.view.IWindowManager;
 import android.view.MotionEvent;
 import android.view.MotionEvent.PointerCoords;
 import android.view.MotionEvent.PointerProperties;
-import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
+import android.view.ScaleGestureDetector;
+import android.view.ScaleGestureDetector.OnScaleGestureListener;
 import android.view.Surface;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -64,6 +68,8 @@
 import com.android.internal.os.SomeArgs;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 
 /**
  * This class handles the screen magnification when accessibility is enabled.
@@ -114,29 +120,28 @@
     private static final boolean DEBUG_VIEWPORT_WINDOW = false;
     private static final boolean DEBUG_WINDOW_TRANSITIONS = false;
     private static final boolean DEBUG_ROTATION = false;
-    private static final boolean DEBUG_GESTURE_DETECTOR = false;
     private static final boolean DEBUG_MAGNIFICATION_CONTROLLER = false;
 
     private static final String LOG_TAG = ScreenMagnifier.class.getSimpleName();
 
     private static final int STATE_DELEGATING = 1;
     private static final int STATE_DETECTING = 2;
-    private static final int STATE_SCALING = 3;
-    private static final int STATE_VIEWPORT_DRAGGING = 4;
-    private static final int STATE_PANNING = 5;
-    private static final int STATE_DECIDE_PAN_OR_SCALE = 6;
+    private static final int STATE_VIEWPORT_DRAGGING = 3;
+    private static final int STATE_MAGNIFIED_INTERACTION = 4;
 
     private static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f;
     private static final int DEFAULT_SCREEN_MAGNIFICATION_AUTO_UPDATE = 1;
     private static final float DEFAULT_WINDOW_ANIMATION_SCALE = 1.0f;
 
+    private static final int MULTI_TAP_TIME_SLOP_ADJUSTMENT = 50;
+
     private final IWindowManager mWindowManagerService = IWindowManager.Stub.asInterface(
             ServiceManager.getService("window"));
     private final WindowManager mWindowManager;
     private final DisplayProvider mDisplayProvider;
 
     private final DetectingStateHandler mDetectingStateHandler = new DetectingStateHandler();
-    private final GestureDetector mGestureDetector;
+    private final MagnifiedContentInteractonStateHandler mMagnifiedContentInteractonStateHandler;
     private final StateViewportDraggingHandler mStateViewportDraggingHandler =
             new StateViewportDraggingHandler();
 
@@ -144,10 +149,12 @@
 
     private final MagnificationController mMagnificationController;
     private final DisplayContentObserver mDisplayContentObserver;
+    private final ScreenStateObserver mScreenStateObserver;
     private final Viewport mViewport;
 
     private final int mTapTimeSlop = ViewConfiguration.getTapTimeout();
-    private final int mMultiTapTimeSlop = ViewConfiguration.getDoubleTapTimeout();
+    private final int mMultiTapTimeSlop =
+            ViewConfiguration.getDoubleTapTimeout() - MULTI_TAP_TIME_SLOP_ADJUSTMENT;
     private final int mTapDistanceSlop;
     private final int mMultiTapDistanceSlop;
 
@@ -160,6 +167,7 @@
     private EventStreamTransformation mNext;
 
     private int mCurrentState;
+    private int mPreviousState;
     private boolean mTranslationEnabledBeforePan;
 
     private PointerCoords[] mTempPointerCoords;
@@ -185,14 +193,18 @@
         mDisplayContentObserver = new DisplayContentObserver(mContext, mViewport,
                 mMagnificationController, mWindowManagerService, mDisplayProvider,
                 mLongAnimationDuration, mWindowAnimationScale);
+        mScreenStateObserver = new ScreenStateObserver(mContext, mViewport,
+                mMagnificationController);
 
-        mGestureDetector = new GestureDetector(context);
+        mMagnifiedContentInteractonStateHandler = new MagnifiedContentInteractonStateHandler(
+                context);
 
         transitionToState(STATE_DETECTING);
     }
 
     @Override
     public void onMotionEvent(MotionEvent event, int policyFlags) {
+        mMagnifiedContentInteractonStateHandler.onMotionEvent(event);
         switch (mCurrentState) {
             case STATE_DELEGATING: {
                 handleMotionEventStateDelegating(event, policyFlags);
@@ -203,18 +215,15 @@
             case STATE_VIEWPORT_DRAGGING: {
                 mStateViewportDraggingHandler.onMotionEvent(event, policyFlags);
             } break;
-            case STATE_SCALING:
-            case STATE_PANNING:
-            case STATE_DECIDE_PAN_OR_SCALE: {
-                // Handled by the gesture detector. Since the detector
-                // needs all touch events to work properly we cannot
-                // call it only for these states.
+            case STATE_MAGNIFIED_INTERACTION: {
+                // mMagnifiedContentInteractonStateHandler handles events only
+                // if this is the current state since it uses ScaleGestureDetecotr
+                // and a GestureDetector which need well formed event stream.
             } break;
             default: {
                 throw new IllegalStateException("Unknown state: " + mCurrentState);
             }
         }
-        mGestureDetector.onMotionEvent(event);
     }
 
     @Override
@@ -234,7 +243,7 @@
         mCurrentState = STATE_DETECTING;
         mDetectingStateHandler.clear();
         mStateViewportDraggingHandler.clear();
-        mGestureDetector.clear();
+        mMagnifiedContentInteractonStateHandler.clear();
         if (mNext != null) {
             mNext.clear();
         }
@@ -247,6 +256,7 @@
         mViewport.setFrameShown(false, true);
         mDisplayProvider.destroy();
         mDisplayContentObserver.destroy();
+        mScreenStateObserver.destroy();
     }
 
     private void handleMotionEventStateDelegating(MotionEvent event, int policyFlags) {
@@ -326,135 +336,103 @@
                 case STATE_VIEWPORT_DRAGGING: {
                     Slog.i(LOG_TAG, "mCurrentState: STATE_VIEWPORT_DRAGGING");
                 } break;
-                case STATE_SCALING: {
-                    Slog.i(LOG_TAG, "mCurrentState: STATE_SCALING");
-                } break;
-                case STATE_PANNING: {
-                    Slog.i(LOG_TAG, "mCurrentState: STATE_PANNING");
-                } break;
-                case STATE_DECIDE_PAN_OR_SCALE: {
-                    Slog.i(LOG_TAG, "mCurrentState: STATE_DECIDE_PAN_OR_SCALE");
+                case STATE_MAGNIFIED_INTERACTION: {
+                    Slog.i(LOG_TAG, "mCurrentState: STATE_MAGNIFIED_INTERACTION");
                 } break;
                 default: {
                     throw new IllegalArgumentException("Unknown state: " + state);
                 }
             }
         }
+        mPreviousState = mCurrentState;
         mCurrentState = state;
     }
 
-    private final class GestureDetector implements OnScaleGestureListener {
+    private final class MagnifiedContentInteractonStateHandler
+            extends SimpleOnGestureListener implements OnScaleGestureListener {
         private static final float MIN_SCALE = 1.3f;
         private static final float MAX_SCALE = 5.0f;
 
-        private static final float DETECT_SCALING_THRESHOLD = 0.25f;
-        private static final int DETECT_PANNING_THRESHOLD_DIP = 30;
-
-        private final float mScaledDetectPanningThreshold;
+        private static final float SCALING_THRESHOLD = 0.3f;
 
         private final ScaleGestureDetector mScaleGestureDetector;
+        private final GestureDetector mGestureDetector;
 
-        private final PointF mPrevFocus = new PointF(Float.NaN, Float.NaN);
-        private final PointF mInitialFocus = new PointF(Float.NaN, Float.NaN);
+        private float mInitialScaleFactor = -1;
+        private boolean mScaling;
 
-        private float mCurrScale = Float.NaN;
-        private float mCurrScaleFactor = 1.0f;
-        private float mPrevScaleFactor = 1.0f;
-        private float mCurrPan;
-        private float mPrevPan;
-
-        private float mScaleFocusX = Float.NaN;
-        private float mScaleFocusY = Float.NaN;
-
-        public GestureDetector(Context context) {
-            final float density = context.getResources().getDisplayMetrics().density;
-            mScaledDetectPanningThreshold = DETECT_PANNING_THRESHOLD_DIP * density;
-            mScaleGestureDetector = new ScaleGestureDetector(this);
+        public MagnifiedContentInteractonStateHandler(Context context) {
+            mScaleGestureDetector = new ScaleGestureDetector(context, this);
+            mGestureDetector = new GestureDetector(context, this);
         }
 
         public void onMotionEvent(MotionEvent event) {
             mScaleGestureDetector.onTouchEvent(event);
-            switch (mCurrentState) {
-                case STATE_DETECTING:
-                case STATE_DELEGATING:
-                case STATE_VIEWPORT_DRAGGING: {
-                    return;
-                }
+            mGestureDetector.onTouchEvent(event);
+            if (mCurrentState != STATE_MAGNIFIED_INTERACTION) {
+                return;
             }
             if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                 clear();
-                if (mCurrentState == STATE_SCALING) {
-                    persistScale(mMagnificationController.getScale());
+                final float scale = mMagnificationController.getScale();
+                if (scale != getPersistedScale()) {
+                    persistScale(scale);
                 }
-                transitionToState(STATE_DETECTING);
+                if (mPreviousState == STATE_VIEWPORT_DRAGGING) {
+                    transitionToState(STATE_VIEWPORT_DRAGGING);
+                } else {
+                    transitionToState(STATE_DETECTING);
+                }
             }
         }
 
         @Override
+        public boolean onScroll(MotionEvent first, MotionEvent second, float distanceX,
+                float distanceY) {
+            if (mCurrentState != STATE_MAGNIFIED_INTERACTION) {
+                return true;
+            }
+            final float scale = mMagnificationController.getScale();
+            final float scrollX = distanceX / scale;
+            final float scrollY = distanceY / scale;
+            final float centerX = mMagnificationController.getMagnifiedRegionCenterX() + scrollX;
+            final float centerY = mMagnificationController.getMagnifiedRegionCenterY() + scrollY;
+            if (DEBUG_PANNING) {
+                Slog.i(LOG_TAG, "Panned content by scrollX: " + scrollX
+                        + " scrollY: " + scrollY);
+            }
+            mMagnificationController.setMagnifiedRegionCenter(centerX, centerY, false);
+            return true;
+        }
+
+        @Override
         public boolean onScale(ScaleGestureDetector detector) {
-            switch (mCurrentState) {
-                case STATE_DETECTING:
-                case STATE_DELEGATING:
-                case STATE_VIEWPORT_DRAGGING: {
-                    return true;
+            if (!mScaling) {
+                if (mInitialScaleFactor < 0) {
+                    mInitialScaleFactor = detector.getScaleFactor();
+                } else {
+                    final float deltaScale = detector.getScaleFactor() - mInitialScaleFactor;
+                    if (Math.abs(deltaScale) > SCALING_THRESHOLD) {
+                        mScaling = true;
+                        return true;
+                    }
                 }
-                case STATE_DECIDE_PAN_OR_SCALE: {
-                    mCurrScaleFactor = mScaleGestureDetector.getScaleFactor();
-                    final float scaleDelta = Math.abs(1.0f - mCurrScaleFactor * mPrevScaleFactor);
-                    if (DEBUG_GESTURE_DETECTOR) {
-                        Slog.i(LOG_TAG, "scaleDelta: " + scaleDelta);
-                    }
-                    if (scaleDelta > DETECT_SCALING_THRESHOLD) {
-                        performScale(detector, true);
-                        clear();
-                        transitionToState(STATE_SCALING);
-                        return true;
-                    }
-                    mCurrPan = (float) MathUtils.dist(
-                            mScaleGestureDetector.getFocusX(),
-                            mScaleGestureDetector.getFocusY(),
-                            mInitialFocus.x, mInitialFocus.y);
-                    final float panDelta = mCurrPan + mPrevPan;
-                    if (DEBUG_GESTURE_DETECTOR) {
-                        Slog.i(LOG_TAG, "panDelta: " + panDelta);
-                    }
-                    if (panDelta > mScaledDetectPanningThreshold) {
-                        performPan(detector, true);
-                        clear();
-                        transitionToState(STATE_PANNING);
-                        return true;
-                    }
-                } break;
-                case STATE_SCALING: {
-                    performScale(detector, false);
-                } break;
-                case STATE_PANNING: {
-                    performPan(detector, false);
-                } break;
+                return false;
             }
-            return false;
+            final float newScale = mMagnificationController.getScale()
+                    * detector.getScaleFactor();
+            final float normalizedNewScale = Math.min(Math.max(newScale, MIN_SCALE), MAX_SCALE);
+            if (DEBUG_SCALING) {
+                Slog.i(LOG_TAG, "normalizedNewScale: " + normalizedNewScale);
+            }
+            mMagnificationController.setScale(normalizedNewScale, detector.getFocusX(),
+                    detector.getFocusY(), false);
+            return true;
         }
 
         @Override
         public boolean onScaleBegin(ScaleGestureDetector detector) {
-            switch (mCurrentState) {
-                case STATE_DECIDE_PAN_OR_SCALE: {
-                    mPrevScaleFactor *= mCurrScaleFactor;
-                    mPrevPan += mCurrPan;
-                    mPrevFocus.x = mInitialFocus.x = detector.getFocusX();
-                    mPrevFocus.y = mInitialFocus.y = detector.getFocusY();
-                } break;
-                case STATE_SCALING: {
-                    mPrevScaleFactor = 1.0f;
-                    mCurrScale = Float.NaN;
-                } break;
-                case STATE_PANNING: {
-                    mPrevPan += mCurrPan;
-                    mPrevFocus.x = mInitialFocus.x = detector.getFocusX();
-                    mPrevFocus.y = mInitialFocus.y = detector.getFocusY();
-                } break;
-            }
-            return true;
+            return (mCurrentState == STATE_MAGNIFIED_INTERACTION);
         }
 
         @Override
@@ -462,58 +440,9 @@
             clear();
         }
 
-        public void clear() {
-            mCurrScaleFactor = 1.0f;
-            mPrevScaleFactor = 1.0f;
-            mPrevPan = 0;
-            mCurrPan = 0;
-            mInitialFocus.set(Float.NaN, Float.NaN);
-            mPrevFocus.set(Float.NaN, Float.NaN);
-            mCurrScale = Float.NaN;
-            mScaleFocusX = Float.NaN;
-            mScaleFocusY = Float.NaN;
-        }
-
-        private void performPan(ScaleGestureDetector detector, boolean animate) {
-            if (Float.compare(mPrevFocus.x, Float.NaN) == 0
-                    && Float.compare(mPrevFocus.y, Float.NaN) == 0) {
-                mPrevFocus.set(detector.getFocusX(), detector.getFocusY());
-                return;
-            }
-            final float scale = mMagnificationController.getScale();
-            final float scrollX = (detector.getFocusX() - mPrevFocus.x) / scale;
-            final float scrollY = (detector.getFocusY() - mPrevFocus.y) / scale;
-            final float centerX = mMagnificationController.getMagnifiedRegionCenterX()
-                    - scrollX;
-            final float centerY = mMagnificationController.getMagnifiedRegionCenterY()
-                    - scrollY;
-            if (DEBUG_PANNING) {
-                Slog.i(LOG_TAG, "Panned content by scrollX: " + scrollX
-                        + " scrollY: " + scrollY);
-            }
-            mMagnificationController.setMagnifiedRegionCenter(centerX, centerY, animate);
-            mPrevFocus.set(detector.getFocusX(), detector.getFocusY());
-        }
-
-        private void performScale(ScaleGestureDetector detector, boolean animate) {
-            if (Float.compare(mCurrScale, Float.NaN) == 0) {
-                mCurrScale = mMagnificationController.getScale();
-                return;
-            }
-            final float totalScaleFactor = mPrevScaleFactor * detector.getScaleFactor();
-            final float newScale = mCurrScale * totalScaleFactor;
-            final float normalizedNewScale = Math.min(Math.max(newScale, MIN_SCALE),
-                    MAX_SCALE);
-            if (DEBUG_SCALING) {
-                Slog.i(LOG_TAG, "normalizedNewScale: " + normalizedNewScale);
-            }
-            if (Float.compare(mScaleFocusX, Float.NaN) == 0
-                    && Float.compare(mScaleFocusY, Float.NaN) == 0) {
-                mScaleFocusX = detector.getFocusX();
-                mScaleFocusY = detector.getFocusY();
-            }
-            mMagnificationController.setScale(normalizedNewScale, mScaleFocusX,
-                    mScaleFocusY, animate);
+        private void clear() {
+            mInitialScaleFactor = -1;
+            mScaling = false;
         }
     }
 
@@ -528,7 +457,7 @@
                 }
                 case MotionEvent.ACTION_POINTER_DOWN: {
                     clear();
-                    transitionToState(STATE_SCALING);
+                    transitionToState(STATE_MAGNIFIED_INTERACTION);
                 } break;
                 case MotionEvent.ACTION_MOVE: {
                     if (event.getPointerCount() != 1) {
@@ -625,14 +554,14 @@
                     } else if (mTapCount < ACTION_TAP_COUNT) {
                         Message message = mHandler.obtainMessage(
                                 MESSAGE_TRANSITION_TO_DELEGATING_STATE);
-                        mHandler.sendMessageDelayed(message, mTapTimeSlop + mMultiTapDistanceSlop);
+                        mHandler.sendMessageDelayed(message, mMultiTapTimeSlop);
                     }
                     clearLastDownEvent();
                     mLastDownEvent = MotionEvent.obtain(event);
                 } break;
                 case MotionEvent.ACTION_POINTER_DOWN: {
                     if (mMagnificationController.isMagnifying()) {
-                        transitionToState(STATE_DECIDE_PAN_OR_SCALE);
+                        transitionToState(STATE_MAGNIFIED_INTERACTION);
                         clear();
                     } else {
                         transitionToDelegatingStateAndClear();
@@ -791,6 +720,12 @@
                 DEFAULT_MAGNIFICATION_SCALE);
     }
 
+    private static boolean isScreenMagnificationAutoUpdateEnabled(Context context) {
+        return (Settings.Secure.getInt(context.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
+                DEFAULT_SCREEN_MAGNIFICATION_AUTO_UPDATE) == 1);
+    }
+
     private static final class MotionEventInfo {
 
         private static final int MAX_POOL_SIZE = 10;
@@ -849,6 +784,54 @@
         }
     }
 
+    private static final class ScreenStateObserver extends BroadcastReceiver {
+
+        private static final int MESSAGE_ON_SCREEN_STATE_CHANGE = 1;
+
+        private final Handler mHandler = new Handler() {
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MESSAGE_ON_SCREEN_STATE_CHANGE: {
+                        String action = (String) message.obj;
+                        handleOnScreenStateChange(action);
+                    } break;
+                }
+            }
+        };
+
+        private final Context mContext;
+        private final Viewport mViewport;
+        private final MagnificationController mMagnificationController;
+
+        public ScreenStateObserver(Context context, Viewport viewport,
+                MagnificationController magnificationController) {
+            mContext = context;
+            mViewport = viewport;
+            mMagnificationController = magnificationController;
+            mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+        }
+
+        public void destroy() {
+            mContext.unregisterReceiver(this);
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mHandler.obtainMessage(MESSAGE_ON_SCREEN_STATE_CHANGE,
+                    intent.getAction()).sendToTarget();
+        }
+
+        private void handleOnScreenStateChange(String action) {
+            if (action.equals(Intent.ACTION_SCREEN_OFF)
+                    && mMagnificationController.isMagnifying()
+                    && isScreenMagnificationAutoUpdateEnabled(mContext)) {
+                mMagnificationController.reset(false);
+                mViewport.setFrameShown(false, false);
+            }
+        }
+    }
+
     private static final class DisplayContentObserver {
 
         private static final int MESSAGE_SHOW_VIEWPORT_FRAME = 1;
@@ -964,7 +947,9 @@
                 }
                 if (info.type == WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
                         || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD
-                        || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG) {
+                        || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG
+                        || info.type == WindowManager.LayoutParams.TYPE_KEYGUARD
+                        || info.type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
                     switch (transition) {
                         case WindowManagerPolicy.TRANSIT_ENTER:
                         case WindowManagerPolicy.TRANSIT_SHOW:
@@ -977,7 +962,7 @@
                     switch (transition) {
                         case WindowManagerPolicy.TRANSIT_ENTER:
                         case WindowManagerPolicy.TRANSIT_SHOW: {
-                            if (!magnifying || !screenMagnificationAutoUpdateEnabled(mContext)) {
+                            if (!magnifying || !isScreenMagnificationAutoUpdateEnabled(mContext)) {
                                 break;
                             }
                             final int type = info.type;
@@ -1065,18 +1050,12 @@
 
         private void resetMagnificationIfNeeded() {
             if (mMagnificationController.isMagnifying()
-                    && screenMagnificationAutoUpdateEnabled(mContext)) {
+                    && isScreenMagnificationAutoUpdateEnabled(mContext)) {
                 mMagnificationController.reset(true);
                 mViewport.setFrameShown(false, true);
             }
         }
 
-        private boolean screenMagnificationAutoUpdateEnabled(Context context) {
-            return (Settings.Secure.getInt(context.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
-                    DEFAULT_SCREEN_MAGNIFICATION_AUTO_UPDATE) == 1);
-        }
-
         private String windowTransitionToString(int transition) {
             switch (transition) {
                 case WindowManagerPolicy.TRANSIT_UNSET: {
@@ -1423,7 +1402,9 @@
 
         private final ArrayList<WindowInfo> mTempWindowInfoList = new ArrayList<WindowInfo>();
 
-        private final Rect mTempRect = new Rect();
+        private final Rect mTempRect1 = new Rect();
+        private final Rect mTempRect2 = new Rect();
+        private final Rect mTempRect3 = new Rect();
 
         private final IWindowManager mWindowManagerService;
         private final DisplayProvider mDisplayProvider;
@@ -1492,31 +1473,83 @@
             recomputeBounds(false);
         }
 
+        private final Comparator<WindowInfo> mWindowInfoInverseComparator =
+                new Comparator<WindowInfo>() {
+            @Override
+            public int compare(WindowInfo lhs, WindowInfo rhs) {
+                if (lhs.layer != rhs.layer) {
+                    return rhs.layer - lhs.layer;
+                }
+                if (lhs.touchableRegion.top != rhs.touchableRegion.top) {
+                    return rhs.touchableRegion.top - lhs.touchableRegion.top;
+                }
+                if (lhs.touchableRegion.left != rhs.touchableRegion.left) {
+                    return rhs.touchableRegion.left - lhs.touchableRegion.left;
+                }
+                if (lhs.touchableRegion.right != rhs.touchableRegion.right) {
+                    return rhs.touchableRegion.right - lhs.touchableRegion.right;
+                }
+                if (lhs.touchableRegion.bottom != rhs.touchableRegion.bottom) {
+                    return rhs.touchableRegion.bottom - lhs.touchableRegion.bottom;
+                }
+                return 0;
+            }
+        };
+
         public void recomputeBounds(boolean animate) {
-            Rect frame = mTempRect;
-            frame.set(0, 0, mDisplayProvider.getDisplayInfo().logicalWidth,
-                    mDisplayProvider.getDisplayInfo().logicalHeight);
+            Rect magnifiedFrame = mTempRect1;
+            magnifiedFrame.set(0, 0, 0, 0);
+
+            Rect notMagnifiedFrame = mTempRect2;
+            notMagnifiedFrame.set(0, 0, 0, 0);
+
             ArrayList<WindowInfo> infos = mTempWindowInfoList;
             infos.clear();
+            int windowCount = 0;
             try {
                 mWindowManagerService.getVisibleWindowsForDisplay(
                         mDisplayProvider.getDisplay().getDisplayId(), infos);
-                final int windowCount = infos.size();
+                Collections.sort(infos, mWindowInfoInverseComparator);
+                windowCount = infos.size();
                 for (int i = 0; i < windowCount; i++) {
                     WindowInfo info = infos.get(i);
-                    if (info.type == WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
-                            || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD
-                            || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG) {
-                        subtract(frame, info.touchableRegion);
+                    if (info.type == WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY) {
+                        continue;
                     }
-                    info.recycle();
+                    if (isWindowMagnified(info.type)) {
+                        Rect clippedFrame = mTempRect3;
+                        clippedFrame.set(info.touchableRegion);
+                        subtract(clippedFrame, notMagnifiedFrame);
+                        magnifiedFrame.union(clippedFrame);
+                    } else {
+                        Rect clippedFrame = mTempRect3;
+                        clippedFrame.set(info.touchableRegion);
+                        subtract(clippedFrame, magnifiedFrame);
+                        notMagnifiedFrame.union(clippedFrame);
+                    }
+                    if (magnifiedFrame.bottom >= notMagnifiedFrame.top) {
+                        break;
+                    }
                 }
             } catch (RemoteException re) {
                 /* ignore */
             } finally {
-                infos.clear();
+                for (int i = windowCount - 1; i >= 0; i--) {
+                    infos.remove(i).recycle();
+                }
             }
-            resize(frame, animate);
+
+            final int displayWidth = mDisplayProvider.getDisplayInfo().logicalWidth;
+            final int displayHeight = mDisplayProvider.getDisplayInfo().logicalHeight;
+            magnifiedFrame.intersect(0, 0, displayWidth, displayHeight);
+
+            resize(magnifiedFrame, animate);
+        }
+
+        private boolean isWindowMagnified(int type) {
+            return (type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
+                    && type != WindowManager.LayoutParams.TYPE_INPUT_METHOD
+                    && type != WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
         }
 
         public void rotationChanged() {
@@ -1762,482 +1795,4 @@
             updateDisplayInfo();
         }
     }
-
-    /**
-     * The listener for receiving notifications when gestures occur.
-     * If you want to listen for all the different gestures then implement
-     * this interface. If you only want to listen for a subset it might
-     * be easier to extend {@link SimpleOnScaleGestureListener}.
-     *
-     * An application will receive events in the following order:
-     * <ul>
-     *  <li>One {@link OnScaleGestureListener#onScaleBegin(ScaleGestureDetector)}
-     *  <li>Zero or more {@link OnScaleGestureListener#onScale(ScaleGestureDetector)}
-     *  <li>One {@link OnScaleGestureListener#onScaleEnd(ScaleGestureDetector)}
-     * </ul>
-     */
-    interface OnScaleGestureListener {
-        /**
-         * Responds to scaling events for a gesture in progress.
-         * Reported by pointer motion.
-         *
-         * @param detector The detector reporting the event - use this to
-         *          retrieve extended info about event state.
-         * @return Whether or not the detector should consider this event
-         *          as handled. If an event was not handled, the detector
-         *          will continue to accumulate movement until an event is
-         *          handled. This can be useful if an application, for example,
-         *          only wants to update scaling factors if the change is
-         *          greater than 0.01.
-         */
-        public boolean onScale(ScaleGestureDetector detector);
-
-        /**
-         * Responds to the beginning of a scaling gesture. Reported by
-         * new pointers going down.
-         *
-         * @param detector The detector reporting the event - use this to
-         *          retrieve extended info about event state.
-         * @return Whether or not the detector should continue recognizing
-         *          this gesture. For example, if a gesture is beginning
-         *          with a focal point outside of a region where it makes
-         *          sense, onScaleBegin() may return false to ignore the
-         *          rest of the gesture.
-         */
-        public boolean onScaleBegin(ScaleGestureDetector detector);
-
-        /**
-         * Responds to the end of a scale gesture. Reported by existing
-         * pointers going up.
-         *
-         * Once a scale has ended, {@link ScaleGestureDetector#getFocusX()}
-         * and {@link ScaleGestureDetector#getFocusY()} will return the location
-         * of the pointer remaining on the screen.
-         *
-         * @param detector The detector reporting the event - use this to
-         *          retrieve extended info about event state.
-         */
-        public void onScaleEnd(ScaleGestureDetector detector);
-    }
-
-    class ScaleGestureDetector {
-
-        private final MinCircleFinder mMinCircleFinder = new MinCircleFinder();
-
-        private final OnScaleGestureListener mListener;
-
-        private float mFocusX;
-        private float mFocusY;
-
-        private float mCurrSpan;
-        private float mPrevSpan;
-        private float mCurrSpanX;
-        private float mCurrSpanY;
-        private float mPrevSpanX;
-        private float mPrevSpanY;
-        private long mCurrTime;
-        private long mPrevTime;
-        private boolean mInProgress;
-
-        public ScaleGestureDetector(OnScaleGestureListener listener) {
-            mListener = listener;
-        }
-
-        /**
-         * Accepts MotionEvents and dispatches events to a {@link OnScaleGestureListener}
-         * when appropriate.
-         *
-         * <p>Applications should pass a complete and consistent event stream to this method.
-         * A complete and consistent event stream involves all MotionEvents from the initial
-         * ACTION_DOWN to the final ACTION_UP or ACTION_CANCEL.</p>
-         *
-         * @param event The event to process
-         * @return true if the event was processed and the detector wants to receive the
-         *         rest of the MotionEvents in this event stream.
-         */
-        public boolean onTouchEvent(MotionEvent event) {
-            boolean streamEnded = false;
-            boolean contextChanged = false;
-            int excludedPtrIdx = -1;
-            final int action = event.getActionMasked();
-            switch (action) {
-                case MotionEvent.ACTION_DOWN:
-                case MotionEvent.ACTION_POINTER_DOWN: {
-                    contextChanged = true;
-                } break;
-                case MotionEvent.ACTION_POINTER_UP: {
-                    contextChanged = true;
-                    excludedPtrIdx = event.getActionIndex();
-                } break;
-                case MotionEvent.ACTION_UP:
-                case MotionEvent.ACTION_CANCEL: {
-                    streamEnded = true;
-                } break;
-            }
-
-            if (mInProgress && (contextChanged || streamEnded)) {
-                mListener.onScaleEnd(this);
-                mInProgress = false;
-                mPrevSpan = 0;
-                mPrevSpanX = 0;
-                mPrevSpanY = 0;
-                return true;
-            }
-
-            final long currTime = mCurrTime;
-
-            mFocusX = 0;
-            mFocusY = 0;
-            mCurrSpan = 0;
-            mCurrSpanX = 0;
-            mCurrSpanY = 0;
-            mCurrTime = 0;
-            mPrevTime = 0;
-
-            if (!streamEnded) {
-                MinCircleFinder.Circle circle =
-                        mMinCircleFinder.computeMinCircleAroundPointers(event);
-                mFocusX = circle.centerX;
-                mFocusY = circle.centerY;
-
-                double sumSlope = 0;
-                final int pointerCount = event.getPointerCount();
-                for (int i = 0; i < pointerCount; i++) {
-                    if (i == excludedPtrIdx) {
-                        continue;
-                    }
-                    float x = event.getX(i) - mFocusX;
-                    float y = event.getY(i) - mFocusY;
-                    if (x == 0) {
-                        x += 0.1f;
-                    }
-                    sumSlope += y / x;
-                }
-                final double avgSlope = sumSlope
-                        / ((excludedPtrIdx < 0) ? pointerCount : pointerCount - 1);
-
-                double angle = Math.atan(avgSlope);
-                mCurrSpan = 2 * circle.radius;
-                mCurrSpanX = (float) Math.abs((Math.cos(angle) * mCurrSpan));
-                mCurrSpanY = (float) Math.abs((Math.sin(angle) * mCurrSpan));
-            }
-
-            if (contextChanged || mPrevSpan == 0 || mPrevSpanX == 0 || mPrevSpanY == 0) {
-                mPrevSpan = mCurrSpan;
-                mPrevSpanX = mCurrSpanX;
-                mPrevSpanY = mCurrSpanY;
-            }
-
-            if (!mInProgress && mCurrSpan != 0 && !streamEnded) {
-                mInProgress = mListener.onScaleBegin(this);
-            }
-
-            if (mInProgress) {
-                mPrevTime = (currTime != 0) ? currTime : event.getEventTime();
-                mCurrTime = event.getEventTime();
-                if (mCurrSpan == 0) {
-                    mListener.onScaleEnd(this);
-                    mInProgress = false;
-                } else {
-                    if (mListener.onScale(this)) {
-                        mPrevSpanX = mCurrSpanX;
-                        mPrevSpanY = mCurrSpanY;
-                        mPrevSpan = mCurrSpan;
-                    }
-                }
-            }
-
-            return true;
-        }
-
-        /**
-         * Returns {@code true} if a scale gesture is in progress.
-         */
-        public boolean isInProgress() {
-            return mInProgress;
-        }
-
-        /**
-         * Get the X coordinate of the current gesture's focal point.
-         * If a gesture is in progress, the focal point is between
-         * each of the pointers forming the gesture.
-         *
-         * If {@link #isInProgress()} would return false, the result of this
-         * function is undefined.
-         *
-         * @return X coordinate of the focal point in pixels.
-         */
-        public float getFocusX() {
-            return mFocusX;
-        }
-
-        /**
-         * Get the Y coordinate of the current gesture's focal point.
-         * If a gesture is in progress, the focal point is between
-         * each of the pointers forming the gesture.
-         *
-         * If {@link #isInProgress()} would return false, the result of this
-         * function is undefined.
-         *
-         * @return Y coordinate of the focal point in pixels.
-         */
-        public float getFocusY() {
-            return mFocusY;
-        }
-
-        /**
-         * Return the average distance between each of the pointers forming the
-         * gesture in progress through the focal point.
-         *
-         * @return Distance between pointers in pixels.
-         */
-        public float getCurrentSpan() {
-            return mCurrSpan;
-        }
-
-        /**
-         * Return the average X distance between each of the pointers forming the
-         * gesture in progress through the focal point.
-         *
-         * @return Distance between pointers in pixels.
-         */
-        public float getCurrentSpanX() {
-            return mCurrSpanX;
-        }
-
-        /**
-         * Return the average Y distance between each of the pointers forming the
-         * gesture in progress through the focal point.
-         *
-         * @return Distance between pointers in pixels.
-         */
-        public float getCurrentSpanY() {
-            return mCurrSpanY;
-        }
-
-        /**
-         * Return the previous average distance between each of the pointers forming the
-         * gesture in progress through the focal point.
-         *
-         * @return Previous distance between pointers in pixels.
-         */
-        public float getPreviousSpan() {
-            return mPrevSpan;
-        }
-
-        /**
-         * Return the previous average X distance between each of the pointers forming the
-         * gesture in progress through the focal point.
-         *
-         * @return Previous distance between pointers in pixels.
-         */
-        public float getPreviousSpanX() {
-            return mPrevSpanX;
-        }
-
-        /**
-         * Return the previous average Y distance between each of the pointers forming the
-         * gesture in progress through the focal point.
-         *
-         * @return Previous distance between pointers in pixels.
-         */
-        public float getPreviousSpanY() {
-            return mPrevSpanY;
-        }
-
-        /**
-         * Return the scaling factor from the previous scale event to the current
-         * event. This value is defined as
-         * ({@link #getCurrentSpan()} / {@link #getPreviousSpan()}).
-         *
-         * @return The current scaling factor.
-         */
-        public float getScaleFactor() {
-            return mPrevSpan > 0 ? mCurrSpan / mPrevSpan : 1;
-        }
-
-        /**
-         * Return the time difference in milliseconds between the previous
-         * accepted scaling event and the current scaling event.
-         *
-         * @return Time difference since the last scaling event in milliseconds.
-         */
-        public long getTimeDelta() {
-            return mCurrTime - mPrevTime;
-        }
-
-        /**
-         * Return the event time of the current event being processed.
-         *
-         * @return Current event time in milliseconds.
-         */
-        public long getEventTime() {
-            return mCurrTime;
-        }
-    }
-
-    private static final class MinCircleFinder {
-        private final ArrayList<PointHolder> mPoints = new ArrayList<PointHolder>();
-        private final ArrayList<PointHolder> sBoundary = new ArrayList<PointHolder>();
-        private final Circle mMinCircle = new Circle();
-
-        /**
-         * Finds the minimal circle that contains all pointers of a motion event.
-         *
-         * @param event A motion event.
-         * @return The minimal circle.
-         */
-        public Circle computeMinCircleAroundPointers(MotionEvent event) {
-            ArrayList<PointHolder> points = mPoints;
-            points.clear();
-            final int pointerCount = event.getPointerCount();
-            for (int i = 0; i < pointerCount; i++) {
-                PointHolder point = PointHolder.obtain(event.getX(i), event.getY(i));
-                points.add(point);
-            }
-            ArrayList<PointHolder> boundary = sBoundary;
-            boundary.clear();
-            computeMinCircleAroundPointsRecursive(points, boundary, mMinCircle);
-            for (int i = points.size() - 1; i >= 0; i--) {
-                points.remove(i).recycle();
-            }
-            boundary.clear();
-            return mMinCircle;
-        }
-
-        private static void computeMinCircleAroundPointsRecursive(ArrayList<PointHolder> points,
-                ArrayList<PointHolder> boundary, Circle outCircle) {
-            if (points.isEmpty()) {
-                if (boundary.size() == 0) {
-                    outCircle.initialize();
-                } else if (boundary.size() == 1) {
-                    outCircle.initialize(boundary.get(0).mData, boundary.get(0).mData);
-                } else if (boundary.size() == 2) {
-                    outCircle.initialize(boundary.get(0).mData, boundary.get(1).mData);
-                } else if (boundary.size() == 3) {
-                    outCircle.initialize(boundary.get(0).mData, boundary.get(1).mData,
-                            boundary.get(2).mData);
-                }
-                return;
-            }
-            PointHolder point = points.remove(points.size() - 1);
-            computeMinCircleAroundPointsRecursive(points, boundary, outCircle);
-            if (!outCircle.contains(point.mData)) {
-                boundary.add(point);
-                computeMinCircleAroundPointsRecursive(points, boundary, outCircle);
-                boundary.remove(point);
-            }
-            points.add(point);
-        }
-
-        private static final class PointHolder {
-            private static final int MAX_POOL_SIZE = 20;
-            private static PointHolder sPool;
-            private static int sPoolSize;
-
-            private PointHolder mNext;
-            private boolean mIsInPool;
-
-            private final PointF mData = new PointF();
-
-            public static PointHolder obtain(float x, float y) {
-                PointHolder holder;
-                if (sPoolSize > 0) {
-                    sPoolSize--;
-                    holder = sPool;
-                    sPool = sPool.mNext;
-                    holder.mNext = null;
-                    holder.mIsInPool = false;
-                } else {
-                    holder = new PointHolder();
-                }
-                holder.mData.set(x, y);
-                return holder;
-            }
-
-            public void recycle() {
-                if (mIsInPool) {
-                    throw new IllegalStateException("Already recycled.");
-                }
-                clear();
-                if (sPoolSize < MAX_POOL_SIZE) {
-                    sPoolSize++;
-                    mNext = sPool;
-                    sPool = this;
-                    mIsInPool = true;
-                }
-            }
-
-            private void clear() {
-                mData.set(0, 0);
-            }
-        }
-
-        public static final class Circle {
-            public float centerX;
-            public float centerY;
-            public float radius;
-
-            private void initialize() {
-                centerX = 0;
-                centerY = 0;
-                radius = 0;
-            }
-
-            private void initialize(PointF first, PointF second, PointF third) {
-                if (!hasLineWithInfiniteSlope(first, second, third)) {
-                    initializeInternal(first, second, third);
-                } else if (!hasLineWithInfiniteSlope(first, third, second)) {
-                    initializeInternal(first, third, second);
-                } else if (!hasLineWithInfiniteSlope(second, first, third)) {
-                    initializeInternal(second, first, third);
-                } else if (!hasLineWithInfiniteSlope(second, third, first)) {
-                    initializeInternal(second, third, first);
-                } else if (!hasLineWithInfiniteSlope(third, first, second)) {
-                    initializeInternal(third, first, second);
-                } else if (!hasLineWithInfiniteSlope(third, second, first)) {
-                    initializeInternal(third, second, first);
-                } else {
-                    initialize();
-                }
-            }
-
-            private void initialize(PointF first, PointF second) {
-                radius = (float) (Math.hypot(second.x - first.x, second.y - first.y) / 2);
-                centerX = (float) (second.x + first.x) / 2;
-                centerY = (float) (second.y + first.y) / 2;
-            }
-
-            public boolean contains(PointF point) {
-                return (int) (Math.hypot(point.x - centerX, point.y - centerY)) <= radius;
-            }
-
-            private void initializeInternal(PointF first, PointF second, PointF third) {
-                final float x1 = first.x;
-                final float y1 = first.y;
-                final float x2 = second.x;
-                final float y2 = second.y;
-                final float x3 = third.x;
-                final float y3 = third.y;
-
-                final float sl1 = (y2 - y1) / (x2 - x1);
-                final float sl2 = (y3 - y2) / (x3 - x2);
-
-                centerX = (int) ((sl1 * sl2 * (y1 - y3) + sl2 * (x1 + x2) - sl1 * (x2 + x3))
-                        / (2 * (sl2 - sl1)));
-                centerY = (int) (-1 / sl1 * (centerX - (x1 + x2) / 2) + (y1 + y2) / 2);
-                radius = (int) Math.hypot(x1 - centerX, y1 - centerY);
-            }
-
-            private boolean hasLineWithInfiniteSlope(PointF first, PointF second, PointF third) {
-                return (second.x - first.x == 0 || third.x - second.x == 0
-                        || second.y - first.y == 0 || third.y - second.y == 0);
-            }
-
-            @Override
-            public String toString() {
-                return "cetner: [" + centerX + ", " + centerY + "] radius: " + radius;
-            }
-        }
-    }
 }
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 2975880..3bb95a8 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -1763,12 +1763,11 @@
             if (ActivityManager.checkUidPermission(
                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                     uid) == PackageManager.PERMISSION_GRANTED) {
-                List<UserInfo> users = mAm.getUserManager().getUsers();
-                for (int ui=0; ui<users.size() && res.size() < maxNum; ui++) {
-                    final UserInfo user = users.get(ui);
-                    if (mServiceMap.getAllServices(user.id).size() > 0) {
+                int[] users = mAm.getUsersLocked();
+                for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
+                    if (mServiceMap.getAllServices(users[ui]).size() > 0) {
                         Iterator<ServiceRecord> it = mServiceMap.getAllServices(
-                                user.id).iterator();
+                                users[ui]).iterator();
                         while (it.hasNext() && res.size() < maxNum) {
                             res.add(makeRunningServiceInfoLocked(it.next()));
                         }
@@ -1873,14 +1872,13 @@
 
         pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
         try {
-            List<UserInfo> users = mAm.getUserManager().getUsers();
-            for (int ui=0; ui<users.size(); ui++) {
-                final UserInfo user = users.get(ui);
-                if (mServiceMap.getAllServices(user.id).size() > 0) {
+            int[] users = mAm.getUsersLocked();
+            for (int user : users) {
+                if (mServiceMap.getAllServices(user).size() > 0) {
                     boolean printed = false;
                     long nowReal = SystemClock.elapsedRealtime();
                     Iterator<ServiceRecord> it = mServiceMap.getAllServices(
-                            user.id).iterator();
+                            user).iterator();
                     needSep = false;
                     while (it.hasNext()) {
                         ServiceRecord r = it.next();
@@ -1891,10 +1889,10 @@
                             continue;
                         }
                         if (!printed) {
-                            if (ui > 0) {
+                            if (user != 0) {
                                 pw.println();
                             }
-                            pw.println("  User " + user.id + " active services:");
+                            pw.println("  User " + user + " active services:");
                             printed = true;
                         }
                         if (needSep) {
@@ -2070,32 +2068,30 @@
             int opti, boolean dumpAll) {
         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
 
-        List<UserInfo> users = mAm.getUserManager().getUsers();
-        if ("all".equals(name)) {
-            synchronized (this) {
-                for (UserInfo user : users) {
-                    for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
+        synchronized (this) {
+            int[] users = mAm.getUsersLocked();
+            if ("all".equals(name)) {
+                for (int user : users) {
+                    for (ServiceRecord r1 : mServiceMap.getAllServices(user)) {
                         services.add(r1);
                     }
                 }
-            }
-        } else {
-            ComponentName componentName = name != null
-                    ? ComponentName.unflattenFromString(name) : null;
-            int objectId = 0;
-            if (componentName == null) {
-                // Not a '/' separated full component name; maybe an object ID?
-                try {
-                    objectId = Integer.parseInt(name, 16);
-                    name = null;
-                    componentName = null;
-                } catch (RuntimeException e) {
+            } else {
+                ComponentName componentName = name != null
+                        ? ComponentName.unflattenFromString(name) : null;
+                int objectId = 0;
+                if (componentName == null) {
+                    // Not a '/' separated full component name; maybe an object ID?
+                    try {
+                        objectId = Integer.parseInt(name, 16);
+                        name = null;
+                        componentName = null;
+                    } catch (RuntimeException e) {
+                    }
                 }
-            }
 
-            synchronized (this) {
-                for (UserInfo user : users) {
-                    for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
+                for (int user : users) {
+                    for (ServiceRecord r1 : mServiceMap.getAllServices(user)) {
                         if (componentName != null) {
                             if (r1.name.equals(componentName)) {
                                 services.add(r1);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0b2d769..6da8403 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -27,6 +27,7 @@
 import com.android.server.SystemServer;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.pm.UserManagerService;
 import com.android.server.wm.WindowManagerService;
 
 import dalvik.system.Zygote;
@@ -99,6 +100,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IPermissionController;
+import android.os.IUserManager;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
@@ -112,7 +114,6 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.provider.Settings;
 import android.text.format.Time;
 import android.util.EventLog;
@@ -811,7 +812,7 @@
     static ActivityThread mSystemThread;
 
     private int mCurrentUserId;
-    private UserManager mUserManager;
+    private UserManagerService mUserManager;
 
     private final class AppDeathRecipient implements IBinder.DeathRecipient {
         final ProcessRecord mApp;
@@ -3401,10 +3402,12 @@
     }
     
     public boolean clearApplicationUserData(final String packageName,
-            final IPackageDataObserver observer, final int userId) {
+            final IPackageDataObserver observer, int userId) {
         enforceNotIsolatedCaller("clearApplicationUserData");
         int uid = Binder.getCallingUid();
         int pid = Binder.getCallingPid();
+        userId = handleIncomingUserLocked(pid, uid,
+                userId, false, true, "clearApplicationUserData", null);
         long callingId = Binder.clearCallingIdentity();
         try {
             IPackageManager pm = AppGlobals.getPackageManager();
@@ -3446,7 +3449,7 @@
         return true;
     }
 
-    public void killBackgroundProcesses(final String packageName) {
+    public void killBackgroundProcesses(final String packageName, int userId) {
         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
                 != PackageManager.PERMISSION_GRANTED &&
                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
@@ -3458,22 +3461,23 @@
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
-        
-        int userId = UserHandle.getCallingUserId();
+
+        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, true, true, "killBackgroundProcesses", null);
         long callingId = Binder.clearCallingIdentity();
         try {
             IPackageManager pm = AppGlobals.getPackageManager();
-            int pkgUid = -1;
             synchronized(this) {
+                int appId = -1;
                 try {
-                    pkgUid = pm.getPackageUid(packageName, userId);
+                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
                 } catch (RemoteException e) {
                 }
-                if (pkgUid == -1) {
+                if (appId == -1) {
                     Slog.w(TAG, "Invalid packageName: " + packageName);
                     return;
                 }
-                killPackageProcessesLocked(packageName, pkgUid, -1,
+                killPackageProcessesLocked(packageName, appId, userId,
                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
             }
         } finally {
@@ -3523,7 +3527,7 @@
         }
     }
 
-    public void forceStopPackage(final String packageName) {
+    public void forceStopPackage(final String packageName, int userId) {
         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
                 != PackageManager.PERMISSION_GRANTED) {
             String msg = "Permission Denial: forceStopPackage() from pid="
@@ -3533,27 +3537,34 @@
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
-        final int userId = UserHandle.getCallingUserId();
+        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, true, true, "forceStopPackage", null);
         long callingId = Binder.clearCallingIdentity();
         try {
             IPackageManager pm = AppGlobals.getPackageManager();
-            int pkgUid = -1;
             synchronized(this) {
-                try {
-                    pkgUid = pm.getPackageUid(packageName, userId);
-                } catch (RemoteException e) {
-                }
-                if (pkgUid == -1) {
-                    Slog.w(TAG, "Invalid packageName: " + packageName);
-                    return;
-                }
-                forceStopPackageLocked(packageName, pkgUid);
-                try {
-                    pm.setPackageStoppedState(packageName, true, userId);
-                } catch (RemoteException e) {
-                } catch (IllegalArgumentException e) {
-                    Slog.w(TAG, "Failed trying to unstop package "
-                            + packageName + ": " + e);
+                int[] users = userId == UserHandle.USER_ALL
+                        ? getUsersLocked() : new int[] { userId };
+                for (int user : users) {
+                    int pkgUid = -1;
+                    try {
+                        pkgUid = pm.getPackageUid(packageName, user);
+                    } catch (RemoteException e) {
+                    }
+                    if (pkgUid == -1) {
+                        Slog.w(TAG, "Invalid packageName: " + packageName);
+                        continue;
+                    }
+                    try {
+                        pm.setPackageStoppedState(packageName, true, user);
+                    } catch (RemoteException e) {
+                    } catch (IllegalArgumentException e) {
+                        Slog.w(TAG, "Failed trying to unstop package "
+                                + packageName + ": " + e);
+                    }
+                    if (isUserRunningLocked(user)) {
+                        forceStopPackageLocked(packageName, pkgUid);
+                    }
                 }
             }
         } finally {
@@ -3685,8 +3696,8 @@
     }
 
     private void forceStopPackageLocked(final String packageName, int uid) {
-        forceStopPackageLocked(packageName, uid, false, false, true, false,
-                UserHandle.getUserId(uid));
+        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
+                false, true, false, UserHandle.getUserId(uid));
         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
                 Uri.fromParts("package", packageName, null));
         if (!mProcessesReady) {
@@ -13688,7 +13699,7 @@
         mAutoStopProfiler = false;
     }
 
-    public boolean profileControl(String process, boolean start,
+    public boolean profileControl(String process, int userId, boolean start,
             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
 
         try {
@@ -13707,22 +13718,7 @@
 
                 ProcessRecord proc = null;
                 if (process != null) {
-                    try {
-                        int pid = Integer.parseInt(process);
-                        synchronized (mPidsSelfLocked) {
-                            proc = mPidsSelfLocked.get(pid);
-                        }
-                    } catch (NumberFormatException e) {
-                    }
-
-                    if (proc == null) {
-                        HashMap<String, SparseArray<ProcessRecord>> all
-                                = mProcessNames.getMap();
-                        SparseArray<ProcessRecord> procs = all.get(process);
-                        if (procs != null && procs.size() > 0) {
-                            proc = procs.valueAt(0);
-                        }
-                    }
+                    proc = findProcessLocked(process, userId, "profileControl");
                 }
 
                 if (start && (proc == null || proc.thread == null)) {
@@ -13766,7 +13762,40 @@
         }
     }
 
-    public boolean dumpHeap(String process, boolean managed,
+    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
+        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, true, true, callName, null);
+        ProcessRecord proc = null;
+        try {
+            int pid = Integer.parseInt(process);
+            synchronized (mPidsSelfLocked) {
+                proc = mPidsSelfLocked.get(pid);
+            }
+        } catch (NumberFormatException e) {
+        }
+
+        if (proc == null) {
+            HashMap<String, SparseArray<ProcessRecord>> all
+                    = mProcessNames.getMap();
+            SparseArray<ProcessRecord> procs = all.get(process);
+            if (procs != null && procs.size() > 0) {
+                proc = procs.valueAt(0);
+                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
+                    for (int i=1; i<procs.size(); i++) {
+                        ProcessRecord thisProc = procs.valueAt(i);
+                        if (thisProc.userId == userId) {
+                            proc = thisProc;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        return proc;
+    }
+
+    public boolean dumpHeap(String process, int userId, boolean managed,
             String path, ParcelFileDescriptor fd) throws RemoteException {
 
         try {
@@ -13783,24 +13812,7 @@
                     throw new IllegalArgumentException("null fd");
                 }
 
-                ProcessRecord proc = null;
-                try {
-                    int pid = Integer.parseInt(process);
-                    synchronized (mPidsSelfLocked) {
-                        proc = mPidsSelfLocked.get(pid);
-                    }
-                } catch (NumberFormatException e) {
-                }
-
-                if (proc == null) {
-                    HashMap<String, SparseArray<ProcessRecord>> all
-                            = mProcessNames.getMap();
-                    SparseArray<ProcessRecord> procs = all.get(process);
-                    if (procs != null && procs.size() > 0) {
-                        proc = procs.valueAt(0);
-                    }
-                }
-
+                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
                 if (proc == null || proc.thread == null) {
                     throw new IllegalArgumentException("Unknown process: " + process);
                 }
@@ -13864,6 +13876,9 @@
                 return true;
             }
 
+            mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
+                    R.anim.screen_user_enter);
+
             // If the user we are switching to is not currently started, then
             // we need to start it now.
             if (mStartedUsers.get(userId) == null) {
@@ -13877,6 +13892,8 @@
             boolean haveActivities = mMainStack.switchUser(userId);
             if (!haveActivities) {
                 startHomeActivityLocked(userId, mStartedUsers.get(userId));
+            } else {
+                mMainStack.addStartingUserLocked(mStartedUsers.get(userId));
             }
         }
 
@@ -13907,6 +13924,7 @@
                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
                         false, false, MY_PID, Process.SYSTEM_UID, userId);
             }
+            mWindowManager.stopFreezingScreen();
         }
     }
 
@@ -14018,7 +14036,7 @@
             throw new SecurityException(msg);
         }
         synchronized (this) {
-            return getUserManager().getUserInfo(mCurrentUserId);
+            return getUserManagerLocked().getUserInfo(mCurrentUserId);
         }
     }
 
@@ -14034,19 +14052,32 @@
             throw new SecurityException(msg);
         }
         synchronized (this) {
-            UserStartedState state = mStartedUsers.get(userId);
-            return state != null && state.mState != UserStartedState.STATE_STOPPING;
+            return isUserRunningLocked(userId);
         }
     }
 
-    private boolean userExists(int userId) {
-        UserInfo user = getUserManager().getUserInfo(userId);
-        return user != null;
+    boolean isUserRunningLocked(int userId) {
+        UserStartedState state = mStartedUsers.get(userId);
+        return state != null && state.mState != UserStartedState.STATE_STOPPING;
     }
 
-    UserManager getUserManager() {
+    private boolean userExists(int userId) {
+        if (userId == 0) {
+            return true;
+        }
+        UserManagerService ums = getUserManagerLocked();
+        return ums != null ? (ums.getUserInfo(userId) != null) : false;
+    }
+
+    int[] getUsersLocked() {
+        UserManagerService ums = getUserManagerLocked();
+        return ums != null ? ums.getUserIds() : new int[] { 0 };
+    }
+
+    UserManagerService getUserManagerLocked() {
         if (mUserManager == null) {
-            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
+            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
         }
         return mUserManager;
     }
diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/java/com/android/server/display/DisplayDevice.java
index 8eeefb4..f5aa3d4 100644
--- a/services/java/com/android/server/display/DisplayDevice.java
+++ b/services/java/com/android/server/display/DisplayDevice.java
@@ -176,6 +176,12 @@
         } else {
             viewport.physicalFrame.setEmpty();
         }
+
+        boolean isRotated = (mCurrentOrientation == Surface.ROTATION_90
+                || mCurrentOrientation == Surface.ROTATION_270);
+        DisplayDeviceInfo info = getDisplayDeviceInfoLocked();
+        viewport.deviceWidth = isRotated ? info.height : info.width;
+        viewport.deviceHeight = isRotated ? info.width : info.height;
     }
 
     /**
diff --git a/services/java/com/android/server/display/DisplayViewport.java b/services/java/com/android/server/display/DisplayViewport.java
index ed4016d..5080556 100644
--- a/services/java/com/android/server/display/DisplayViewport.java
+++ b/services/java/com/android/server/display/DisplayViewport.java
@@ -44,12 +44,20 @@
     // should be scaled or translated after rotation.
     public final Rect physicalFrame = new Rect();
 
+    // The full width and height of the display device, rotated in the same
+    // manner as physicalFrame.  This expresses the full native size of the display device.
+    // The physical frame should usually fit within this area.
+    public int deviceWidth;
+    public int deviceHeight;
+
     public void copyFrom(DisplayViewport viewport) {
         valid = viewport.valid;
         displayId = viewport.displayId;
         orientation = viewport.orientation;
         logicalFrame.set(viewport.logicalFrame);
         physicalFrame.set(viewport.physicalFrame);
+        deviceWidth = viewport.deviceWidth;
+        deviceHeight = viewport.deviceHeight;
     }
 
     // For debugging purposes.
@@ -60,6 +68,8 @@
                 + ", orientation=" + orientation
                 + ", logicalFrame=" + logicalFrame
                 + ", physicalFrame=" + physicalFrame
+                + ", deviceWidth=" + deviceWidth
+                + ", deviceHeight=" + deviceHeight
                 + "}";
     }
 }
diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java
index ee82050..b75940e 100644
--- a/services/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/java/com/android/server/display/WifiDisplayAdapter.java
@@ -27,7 +27,6 @@
 import android.media.RemoteDisplay;
 import android.os.Handler;
 import android.os.IBinder;
-import android.util.Slog;
 import android.view.Surface;
 
 import java.io.PrintWriter;
@@ -50,8 +49,8 @@
 final class WifiDisplayAdapter extends DisplayAdapter {
     private static final String TAG = "WifiDisplayAdapter";
 
-    private WifiDisplayHandle mDisplayHandle;
     private WifiDisplayController mDisplayController;
+    private WifiDisplayDevice mDisplayDevice;
 
     private WifiDisplayStatus mCurrentStatus;
     private boolean mEnabled;
@@ -71,13 +70,6 @@
     public void dumpLocked(PrintWriter pw) {
         super.dumpLocked(pw);
 
-        if (mDisplayHandle == null) {
-            pw.println("mDisplayHandle=null");
-        } else {
-            pw.println("mDisplayHandle:");
-            mDisplayHandle.dumpLocked(pw);
-        }
-
         pw.println("mCurrentStatus=" + getWifiDisplayStatusLocked());
         pw.println("mEnabled=" + mEnabled);
         pw.println("mScanState=" + mScanState);
@@ -151,16 +143,29 @@
         return mCurrentStatus;
     }
 
-    private void handleConnectLocked(WifiDisplay display, String iface) {
+    private void handleConnectLocked(WifiDisplay display,
+            Surface surface, int width, int height, int flags) {
         handleDisconnectLocked();
 
-        mDisplayHandle = new WifiDisplayHandle(display.getDeviceName(), iface);
+        int deviceFlags = 0;
+        if ((flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0) {
+            deviceFlags |= DisplayDeviceInfo.FLAG_SECURE;
+        }
+
+        float refreshRate = 60.0f; // TODO: get this for real
+
+        String name = display.getDeviceName();
+        IBinder displayToken = Surface.createDisplay(name);
+        mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height,
+                refreshRate, deviceFlags, surface);
+        sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED);
     }
 
     private void handleDisconnectLocked() {
-        if (mDisplayHandle != null) {
-            mDisplayHandle.disposeLocked();
-            mDisplayHandle = null;
+        if (mDisplayDevice != null) {
+            mDisplayDevice.clearSurfaceLocked();
+            sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
+            mDisplayDevice = null;
         }
     }
 
@@ -258,9 +263,10 @@
         }
 
         @Override
-        public void onDisplayConnected(WifiDisplay display, String iface) {
+        public void onDisplayConnected(WifiDisplay display, Surface surface,
+                int width, int height, int flags) {
             synchronized (getSyncRoot()) {
-                handleConnectLocked(display, iface);
+                handleConnectLocked(display, surface, width, height, flags);
 
                 if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTED
                         || mActiveDisplay == null
@@ -337,92 +343,4 @@
             return mInfo;
         }
     }
-
-    private final class WifiDisplayHandle implements RemoteDisplay.Listener {
-        private final String mName;
-        private final String mIface;
-        private final RemoteDisplay mRemoteDisplay;
-
-        private WifiDisplayDevice mDevice;
-        private int mLastError;
-
-        public WifiDisplayHandle(String name, String iface) {
-            mName = name;
-            mIface = iface;
-            mRemoteDisplay = RemoteDisplay.listen(iface, this, getHandler());
-
-            Slog.i(TAG, "Listening for Wifi display connections on " + iface
-                    + " from " + mName);
-        }
-
-        public void disposeLocked() {
-            Slog.i(TAG, "Stopped listening for Wifi display connections on " + mIface
-                    + " from " + mName);
-
-            removeDisplayLocked();
-            mRemoteDisplay.dispose();
-        }
-
-        public void dumpLocked(PrintWriter pw) {
-            pw.println("  " + mName + ": " + (mDevice != null ? "connected" : "disconnected"));
-            pw.println("    mIface=" + mIface);
-            pw.println("    mLastError=" + mLastError);
-        }
-
-        // Called on the handler thread.
-        @Override
-        public void onDisplayConnected(Surface surface, int width, int height, int flags) {
-            synchronized (getSyncRoot()) {
-                mLastError = 0;
-                removeDisplayLocked();
-                addDisplayLocked(surface, width, height, flags);
-
-                Slog.i(TAG, "Wifi display connected: " + mName);
-            }
-        }
-
-        // Called on the handler thread.
-        @Override
-        public void onDisplayDisconnected() {
-            synchronized (getSyncRoot()) {
-                mLastError = 0;
-                removeDisplayLocked();
-
-                Slog.i(TAG, "Wifi display disconnected: " + mName);
-            }
-        }
-
-        // Called on the handler thread.
-        @Override
-        public void onDisplayError(int error) {
-            synchronized (getSyncRoot()) {
-                mLastError = error;
-                removeDisplayLocked();
-
-                Slog.i(TAG, "Wifi display disconnected due to error " + error + ": " + mName);
-            }
-        }
-
-        private void addDisplayLocked(Surface surface, int width, int height, int flags) {
-            int deviceFlags = 0;
-            if ((flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0) {
-                deviceFlags |= DisplayDeviceInfo.FLAG_SECURE;
-            }
-
-            float refreshRate = 60.0f; // TODO: get this for real
-
-            IBinder displayToken = Surface.createDisplay(mName);
-            mDevice = new WifiDisplayDevice(displayToken, mName, width, height,
-                    refreshRate, deviceFlags, surface);
-            sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
-        }
-
-        private void removeDisplayLocked() {
-            if (mDevice != null) {
-                mDevice.clearSurfaceLocked();
-                sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_REMOVED);
-                mDevice = null;
-            }
-        }
-    }
 }
diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java
index 67691df..6e0be55 100644
--- a/services/java/com/android/server/display/WifiDisplayController.java
+++ b/services/java/com/android/server/display/WifiDisplayController.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.display.WifiDisplay;
+import android.media.RemoteDisplay;
 import android.net.NetworkInfo;
 import android.net.wifi.p2p.WifiP2pConfig;
 import android.net.wifi.p2p.WifiP2pDevice;
@@ -36,6 +37,7 @@
 import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
 import android.os.Handler;
 import android.util.Slog;
+import android.view.Surface;
 
 import java.io.PrintWriter;
 import java.net.Inet4Address;
@@ -64,6 +66,7 @@
     private static final int DEFAULT_CONTROL_PORT = 7236;
     private static final int MAX_THROUGHPUT = 50;
     private static final int CONNECTION_TIMEOUT_SECONDS = 30;
+    private static final int RTSP_TIMEOUT_SECONDS = 15;
 
     private static final int DISCOVER_PEERS_MAX_RETRIES = 10;
     private static final int DISCOVER_PEERS_RETRY_DELAY_MILLIS = 500;
@@ -104,12 +107,19 @@
     // The group info obtained after connecting.
     private WifiP2pGroup mConnectedDeviceGroupInfo;
 
-    // The device that we announced to the rest of the system.
-    private WifiP2pDevice mPublishedDevice;
-
     // Number of connection retries remaining.
     private int mConnectionRetriesLeft;
 
+    // The remote display that is listening on the connection.
+    // Created after the Wifi P2P network is connected.
+    private RemoteDisplay mRemoteDisplay;
+
+    // The remote display interface.
+    private String mRemoteDisplayInterface;
+
+    // True if RTSP has connected.
+    private boolean mRemoteDisplayConnected;
+
     public WifiDisplayController(Context context, Handler handler, Listener listener) {
         mContext = context;
         mHandler = handler;
@@ -135,8 +145,10 @@
         pw.println("mDesiredDevice=" + describeWifiP2pDevice(mDesiredDevice));
         pw.println("mConnectingDisplay=" + describeWifiP2pDevice(mConnectingDevice));
         pw.println("mConnectedDevice=" + describeWifiP2pDevice(mConnectedDevice));
-        pw.println("mPublishedDevice=" + describeWifiP2pDevice(mPublishedDevice));
         pw.println("mConnectionRetriesLeft=" + mConnectionRetriesLeft);
+        pw.println("mRemoteDisplay=" + mRemoteDisplay);
+        pw.println("mRemoteDisplayInterface=" + mRemoteDisplayInterface);
+        pw.println("mRemoteDisplayConnected=" + mRemoteDisplayConnected);
 
         pw.println("mKnownWifiDisplayPeers: size=" + mKnownWifiDisplayPeers.size());
         for (WifiP2pDevice device : mKnownWifiDisplayPeers) {
@@ -179,7 +191,6 @@
                     if (mWfdEnabling) {
                         mWfdEnabling = false;
                         setWfdEnabled(true);
-                        discoverPeers();
                     }
                 }
 
@@ -342,7 +353,7 @@
     }
 
     private void retryConnection() {
-        if (mDesiredDevice != null && mPublishedDevice != mDesiredDevice
+        if (mDesiredDevice != null && mConnectedDevice != mDesiredDevice
                 && mConnectionRetriesLeft > 0) {
             mConnectionRetriesLeft -= 1;
             Slog.i(TAG, "Retrying Wifi display connection.  Retries left: "
@@ -364,14 +375,22 @@
     private void updateConnection() {
         // Step 1. Before we try to connect to a new device, tell the system we
         // have disconnected from the old one.
-        if (mPublishedDevice != null && mPublishedDevice != mDesiredDevice) {
+        if (mRemoteDisplay != null && mConnectedDevice != mDesiredDevice) {
+            Slog.i(TAG, "Stopped listening for RTSP connection on " + mRemoteDisplayInterface
+                    + " from Wifi display: " + mConnectedDevice.deviceName);
+
+            mRemoteDisplay.dispose();
+            mRemoteDisplay = null;
+            mRemoteDisplayInterface = null;
+            mRemoteDisplayConnected = false;
+            mHandler.removeCallbacks(mRtspTimeout);
+
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
                     mListener.onDisplayDisconnected();
                 }
             });
-            mPublishedDevice = null;
 
             // continue to next step
         }
@@ -472,9 +491,9 @@
 
                 @Override
                 public void onFailure(int reason) {
-                    Slog.i(TAG, "Failed to initiate connection to Wifi display: "
-                            + newDevice.deviceName + ", reason=" + reason);
                     if (mConnectingDevice == newDevice) {
+                        Slog.i(TAG, "Failed to initiate connection to Wifi display: "
+                                + newDevice.deviceName + ", reason=" + reason);
                         mConnectingDevice = null;
                         handleConnectionFailure(false);
                     }
@@ -483,8 +502,8 @@
             return; // wait for asynchronous callback
         }
 
-        // Step 6. Publish the new connection.
-        if (mConnectedDevice != null && mPublishedDevice == null) {
+        // Step 6. Listen for incoming connections.
+        if (mConnectedDevice != null && mRemoteDisplay == null) {
             Inet4Address addr = getInterfaceAddress(mConnectedDeviceGroupInfo);
             if (addr == null) {
                 Slog.i(TAG, "Failed to get local interface address for communicating "
@@ -493,23 +512,57 @@
                 return; // done
             }
 
-            int port = DEFAULT_CONTROL_PORT;
-            if (mConnectedDevice.deviceName.startsWith("DIRECT-")
-                    && mConnectedDevice.deviceName.endsWith("Broadcom")) {
-                // These dongles ignore the port we broadcast in our WFD IE.
-                port = 8554;
-            }
-
-            final WifiDisplay display = createWifiDisplay(mConnectedDevice);
+            final WifiP2pDevice oldDevice = mConnectedDevice;
+            final int port = getPortNumber(mConnectedDevice);
             final String iface = addr.getHostAddress() + ":" + port;
+            mRemoteDisplayInterface = iface;
 
-            mPublishedDevice = mConnectedDevice;
-            mHandler.post(new Runnable() {
+            Slog.i(TAG, "Listening for RTSP connection on " + iface
+                    + " from Wifi display: " + mConnectedDevice.deviceName);
+
+            mRemoteDisplay = RemoteDisplay.listen(iface, new RemoteDisplay.Listener() {
                 @Override
-                public void run() {
-                    mListener.onDisplayConnected(display, iface);
+                public void onDisplayConnected(final Surface surface,
+                        final int width, final int height, final int flags) {
+                    if (mConnectedDevice == oldDevice && !mRemoteDisplayConnected) {
+                        Slog.i(TAG, "Opened RTSP connection with Wifi display: "
+                                + mConnectedDevice.deviceName);
+                        mRemoteDisplayConnected = true;
+                        mHandler.removeCallbacks(mRtspTimeout);
+
+                        final WifiDisplay display = createWifiDisplay(mConnectedDevice);
+                        mHandler.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                mListener.onDisplayConnected(display,
+                                        surface, width, height, flags);
+                            }
+                        });
+                    }
                 }
-            });
+
+                @Override
+                public void onDisplayDisconnected() {
+                    if (mConnectedDevice == oldDevice) {
+                        Slog.i(TAG, "Closed RTSP connection with Wifi display: "
+                                + mConnectedDevice.deviceName);
+                        mHandler.removeCallbacks(mRtspTimeout);
+                        disconnect();
+                    }
+                }
+
+                @Override
+                public void onDisplayError(int error) {
+                    if (mConnectedDevice == oldDevice) {
+                        Slog.i(TAG, "Lost RTSP connection with Wifi display due to error "
+                                + error + ": " + mConnectedDevice.deviceName);
+                        mHandler.removeCallbacks(mRtspTimeout);
+                        handleConnectionFailure(false);
+                    }
+                }
+            }, mHandler);
+
+            mHandler.postDelayed(mRtspTimeout, RTSP_TIMEOUT_SECONDS * 1000);
         }
     }
 
@@ -517,9 +570,7 @@
         if (mWifiP2pEnabled != enabled) {
             mWifiP2pEnabled = enabled;
             if (enabled) {
-                if (mWfdEnabled) {
-                    discoverPeers();
-                } else {
+                if (!mWfdEnabled) {
                     enableWfd();
                 }
             } else {
@@ -600,17 +651,30 @@
         }
     };
 
+    private final Runnable mRtspTimeout = new Runnable() {
+        @Override
+        public void run() {
+            if (mConnectedDevice != null
+                    && mRemoteDisplay != null && !mRemoteDisplayConnected) {
+                Slog.i(TAG, "Timed out waiting for Wifi display RTSP connection after "
+                        + RTSP_TIMEOUT_SECONDS + " seconds: "
+                        + mConnectedDevice.deviceName);
+                handleConnectionFailure(true);
+            }
+        }
+    };
+
     private void handleConnectionFailure(boolean timeoutOccurred) {
+        Slog.i(TAG, "Wifi display connection failed!");
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mListener.onDisplayConnectionFailed();
+            }
+        });
+
         if (mDesiredDevice != null) {
-            Slog.i(TAG, "Wifi display connection failed!");
-
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mListener.onDisplayConnectionFailed();
-                }
-            });
-
             if (mConnectionRetriesLeft > 0) {
                 mHandler.postDelayed(new Runnable() {
                     @Override
@@ -647,12 +711,24 @@
         return null;
     }
 
+    private static int getPortNumber(WifiP2pDevice device) {
+        if (device.deviceName.startsWith("DIRECT-")
+                && device.deviceName.endsWith("Broadcom")) {
+            // These dongles ignore the port we broadcast in our WFD IE.
+            return 8554;
+        }
+        return DEFAULT_CONTROL_PORT;
+    }
+
     private static boolean isWifiDisplay(WifiP2pDevice device) {
-        // FIXME: the wfdInfo API doesn't work yet
-        return device.deviceName.startsWith("DWD-")
-                || device.deviceName.startsWith("DIRECT-")
-                || device.deviceName.startsWith("CAVM-");
-        //device.wfdInfo != null && device.wfdInfo.isWfdEnabled();
+        return device.wfdInfo != null
+                && device.wfdInfo.isWfdEnabled()
+                && isPrimarySinkDeviceType(device.wfdInfo.getDeviceType());
+    }
+
+    private static boolean isPrimarySinkDeviceType(int deviceType) {
+        return deviceType == WifiP2pWfdInfo.PRIMARY_SINK
+                || deviceType == WifiP2pWfdInfo.SOURCE_OR_PRIMARY_SINK;
     }
 
     private static String describeWifiP2pDevice(WifiP2pDevice device) {
@@ -711,7 +787,8 @@
 
         void onDisplayConnecting(WifiDisplay display);
         void onDisplayConnectionFailed();
-        void onDisplayConnected(WifiDisplay display, String iface);
+        void onDisplayConnected(WifiDisplay display,
+                Surface surface, int width, int height, int flags);
         void onDisplayDisconnected();
     }
 }
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 95655a5..805818a 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -149,7 +149,8 @@
     private static native void nativeSetDisplayViewport(int ptr, boolean external,
             int displayId, int rotation,
             int logicalLeft, int logicalTop, int logicalRight, int logicalBottom,
-            int physicalLeft, int physicalTop, int physicalRight, int physicalBottom);
+            int physicalLeft, int physicalTop, int physicalRight, int physicalBottom,
+            int deviceWidth, int deviceHeight);
 
     private static native int nativeGetScanCodeState(int ptr,
             int deviceId, int sourceMask, int scanCode);
@@ -305,7 +306,8 @@
                 viewport.logicalFrame.left, viewport.logicalFrame.top,
                 viewport.logicalFrame.right, viewport.logicalFrame.bottom,
                 viewport.physicalFrame.left, viewport.physicalFrame.top,
-                viewport.physicalFrame.right, viewport.physicalFrame.bottom);
+                viewport.physicalFrame.right, viewport.physicalFrame.bottom,
+                viewport.deviceWidth, viewport.deviceHeight);
     }
 
     /**
diff --git a/services/java/com/android/server/location/ComprehensiveCountryDetector.java b/services/java/com/android/server/location/ComprehensiveCountryDetector.java
index 1026a0d..354858b 100755
--- a/services/java/com/android/server/location/ComprehensiveCountryDetector.java
+++ b/services/java/com/android/server/location/ComprehensiveCountryDetector.java
@@ -384,8 +384,8 @@
     }
 
     protected boolean isAirplaneModeOff() {
-        return Settings.System.getInt(
-                mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 0;
+        return Settings.Global.getInt(
+                mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) == 0;
     }
 
     /**
diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java
index 3329acb..85de349 100644
--- a/services/java/com/android/server/pm/Installer.java
+++ b/services/java/com/android/server/pm/Installer.java
@@ -359,12 +359,20 @@
         return execute("movefiles");
     }
 
+    /**
+     * Links the native library directory in an application's directory to its
+     * real location.
+     *
+     * @param dataPath data directory where the application is
+     * @param nativeLibPath target native library path
+     * @return -1 on error
+     */
     public int linkNativeLibraryDirectory(String dataPath, String nativeLibPath) {
         if (dataPath == null) {
-            Slog.e(TAG, "unlinkNativeLibraryDirectory dataPath is null");
+            Slog.e(TAG, "linkNativeLibraryDirectory dataPath is null");
             return -1;
         } else if (nativeLibPath == null) {
-            Slog.e(TAG, "unlinkNativeLibraryDirectory nativeLibPath is null");
+            Slog.e(TAG, "linkNativeLibraryDirectory nativeLibPath is null");
             return -1;
         }
 
@@ -375,16 +383,4 @@
 
         return execute(builder.toString());
     }
-
-    public int unlinkNativeLibraryDirectory(String dataPath) {
-        if (dataPath == null) {
-            Slog.e(TAG, "unlinkNativeLibraryDirectory dataPath is null");
-            return -1;
-        }
-
-        StringBuilder builder = new StringBuilder("unlinklib ");
-        builder.append(dataPath);
-
-        return execute(builder.toString());
-    }
 }
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 4bb6e38..8ce474a 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -25,6 +25,11 @@
 import static com.android.internal.util.ArrayUtils.appendInt;
 import static com.android.internal.util.ArrayUtils.removeInt;
 import static libcore.io.OsConstants.S_ISLNK;
+import static libcore.io.OsConstants.S_IRWXU;
+import static libcore.io.OsConstants.S_IRGRP;
+import static libcore.io.OsConstants.S_IXGRP;
+import static libcore.io.OsConstants.S_IROTH;
+import static libcore.io.OsConstants.S_IXOTH;
 
 import com.android.internal.app.IMediaContainerService;
 import com.android.internal.app.ResolverActivity;
@@ -104,6 +109,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.Environment.UserEnvironment;
 import android.provider.Settings.Secure;
 import android.security.SystemKeyStore;
 import android.util.DisplayMetrics;
@@ -147,6 +153,7 @@
 import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
 import libcore.io.Libcore;
+import libcore.io.OsConstants;
 import libcore.io.StructStat;
 
 /**
@@ -276,7 +283,7 @@
     // This is the object monitoring mDrmAppPrivateInstallDir.
     final FileObserver mDrmAppInstallObserver;
 
-    // Used for priviledge escalation.  MUST NOT BE CALLED WITH mPackages
+    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
     // LOCK HELD.  Can be called with mInstallLock held.
     final Installer mInstaller;
 
@@ -286,6 +293,12 @@
     final File mAppInstallDir;
     final File mDalvikCacheDir;
 
+    /**
+     * Directory to which applications installed internally have native
+     * libraries copied.
+     */
+    private File mAppLibInstallDir;
+
     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
     // apps.
     final File mDrmAppPrivateInstallDir;
@@ -1215,6 +1228,7 @@
             }
 
             mAppInstallDir = new File(dataDir, "app");
+            mAppLibInstallDir = new File(dataDir, "app-lib");
             //look for any incomplete package installations
             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
             //clean up list
@@ -3607,6 +3621,13 @@
                 res = resInner;
             }
         }
+
+        final File nativeLibraryFile = new File(mAppLibInstallDir, packageName);
+        NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
+        if (!nativeLibraryFile.delete()) {
+            Slog.w(TAG, "Couldn't delete native library directory " + nativeLibraryFile.getPath());
+        }
+
         return res;
     }
 
@@ -4048,9 +4069,7 @@
              */
             if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
                 if (pkgSetting.nativeLibraryPathString == null) {
-                    final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath();
-                    pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
-                    pkgSetting.nativeLibraryPathString = nativeLibraryPath;
+                    setInternalAppNativeLibraryPath(pkg, pkgSetting);
                 } else {
                     pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
                 }
@@ -4072,7 +4091,7 @@
          */
         if (pkg.applicationInfo.nativeLibraryDir != null) {
             try {
-                final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
+                File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
                 final String dataPathString = dataPath.getCanonicalPath();
 
                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
@@ -4087,30 +4106,31 @@
                         Log.i(TAG, "removed obsolete native libraries for system package "
                                 + path);
                     }
-                } else if (nativeLibraryDir.getParentFile().getCanonicalPath()
-                        .equals(dataPathString)) {
-                    /*
-                     * Make sure the native library dir isn't a symlink to
-                     * something. If it is, ask installd to remove it and create
-                     * a directory so we can copy to it afterwards.
-                     */
-                    boolean isSymLink;
-                    try {
-                        isSymLink = S_ISLNK(Libcore.os.lstat(nativeLibraryDir.getPath()).st_mode);
-                    } catch (ErrnoException e) {
-                        // This shouldn't happen, but we'll fail-safe.
-                        isSymLink = true;
-                    }
-                    if (isSymLink) {
-                        mInstaller.unlinkNativeLibraryDirectory(dataPathString);
+                } else if (!isForwardLocked(pkg) && !isExternal(pkg)) {
+                    // Update native library dir if it starts with /data/data
+                    if (nativeLibraryDir.getParent().startsWith(dataPathString)) {
+                        setInternalAppNativeLibraryPath(pkg, pkgSetting);
+                        nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
                     }
 
-                    /*
-                     * If this is an internal application or our
-                     * nativeLibraryPath points to our data directory, unpack
-                     * the libraries if necessary.
-                     */
-                    NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
+                    try {
+                        if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
+                            Slog.e(TAG, "Unable to copy native libraries");
+                            mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+                            return null;
+                        }
+                    } catch (IOException e) {
+                        Slog.e(TAG, "Unable to copy native libraries", e);
+                        mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+                        return null;
+                    }
+
+                    if (mInstaller.linkNativeLibraryDirectory(dataPathString,
+                            pkg.applicationInfo.nativeLibraryDir) == -1) {
+                        Slog.e(TAG, "Unable to link native library directory");
+                        mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+                        return null;
+                    }
                 } else {
                     Slog.i(TAG, "Linking native library dir for " + path);
                     int ret = mInstaller.linkNativeLibraryDirectory(dataPathString,
@@ -4122,7 +4142,7 @@
                     }
                 }
             } catch (IOException ioe) {
-                Log.e(TAG, "Unable to get canonical file " + ioe.toString());
+                Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
             }
         }
         pkg.mScanPath = path;
@@ -4437,6 +4457,41 @@
         return pkg;
     }
 
+    private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
+            PackageSetting pkgSetting) {
+        final String apkLibPath = getApkName(pkgSetting.codePathString);
+        final String nativeLibraryPath = new File(mAppLibInstallDir, apkLibPath).getPath();
+        pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
+        pkgSetting.nativeLibraryPathString = nativeLibraryPath;
+    }
+
+    private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
+            throws IOException {
+        if (!nativeLibraryDir.isDirectory()) {
+            nativeLibraryDir.delete();
+
+            if (!nativeLibraryDir.mkdir()) {
+                throw new IOException("Cannot create " + nativeLibraryDir.getPath());
+            }
+
+            try {
+                Libcore.os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH
+                        | S_IXOTH);
+            } catch (ErrnoException e) {
+                throw new IOException("Cannot chmod native library directory "
+                        + nativeLibraryDir.getPath(), e);
+            }
+        } else if (!SELinux.restorecon(nativeLibraryDir)) {
+            throw new IOException("Cannot set SELinux context for " + nativeLibraryDir.getPath());
+        }
+
+        /*
+         * If this is an internal application or our nativeLibraryPath points to
+         * the app-lib directory, unpack the libraries if necessary.
+         */
+        return NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
+    }
+
     private void killApplication(String pkgName, int appId) {
         // Request the ActivityManager to kill the process(only for existing packages)
         // so that we do not end up in a confused state while the user is still using the older
@@ -6081,19 +6136,20 @@
                 mounted = true;
             } else {
                 final String status = Environment.getExternalStorageState();
-
-                mounted = status.equals(Environment.MEDIA_MOUNTED)
-                        || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
+                mounted = (Environment.MEDIA_MOUNTED.equals(status)
+                        || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
             }
 
             if (mounted) {
-                final File externalCacheDir = Environment
+                final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
+
+                final File externalCacheDir = userEnv
                         .getExternalStorageAppCacheDirectory(mStats.packageName);
                 final long externalCacheSize = mContainerService
                         .calculateDirectorySize(externalCacheDir.getPath());
                 mStats.externalCacheSize = externalCacheSize;
 
-                final File externalDataDir = Environment
+                final File externalDataDir = userEnv
                         .getExternalStorageAppDataDirectory(mStats.packageName);
                 long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir
                         .getPath());
@@ -6103,12 +6159,12 @@
                 }
                 mStats.externalDataSize = externalDataSize;
 
-                final File externalMediaDir = Environment
+                final File externalMediaDir = userEnv
                         .getExternalStorageAppMediaDirectory(mStats.packageName);
                 mStats.externalMediaSize = mContainerService
                         .calculateDirectorySize(externalMediaDir.getPath());
 
-                final File externalObbDir = Environment
+                final File externalObbDir = userEnv
                         .getExternalStorageAppObbDirectory(mStats.packageName);
                 mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir
                         .getPath());
@@ -6737,7 +6793,7 @@
             String apkName = getNextCodePath(null, pkgName, ".apk");
             codeFileName = new File(installDir, apkName + ".apk").getPath();
             resourceFileName = getResourcePathFromCodePath();
-            libraryPath = new File(dataDir, LIB_DIR_NAME).getPath();
+            libraryPath = new File(mAppLibInstallDir, pkgName).getPath();
         }
 
         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
@@ -6774,6 +6830,7 @@
             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
             codeFileName = createTempPackageFile(installDir).getPath();
             resourceFileName = getResourcePathFromCodePath();
+            libraryPath = getLibraryPathFromCodePath();
             created = true;
         }
 
@@ -6828,6 +6885,23 @@
                     return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
                 }
             }
+
+            final File nativeLibraryFile = new File(getNativeLibraryPath());
+            Slog.i(TAG, "Copying native libraries to " + nativeLibraryFile.getPath());
+            if (nativeLibraryFile.exists()) {
+                NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
+                nativeLibraryFile.delete();
+            }
+            try {
+                int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
+                if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
+                    return copyRet;
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "Copying native libraries failed", e);
+                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+            }
+
             return ret;
         }
 
@@ -6845,6 +6919,7 @@
             } else {
                 final File oldCodeFile = new File(getCodePath());
                 final File oldResourceFile = new File(getResourcePath());
+                final File oldLibraryFile = new File(getNativeLibraryPath());
 
                 // Rename APK file based on packageName
                 final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
@@ -6859,7 +6934,20 @@
                 if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) {
                     return false;
                 }
-                resourceFileName = getResourcePathFromCodePath();
+                resourceFileName = newResFile.getPath();
+
+                // Rename library path
+                final File newLibraryFile = new File(getLibraryPathFromCodePath());
+                if (newLibraryFile.exists()) {
+                    NativeLibraryHelper.removeNativeBinariesFromDirLI(newLibraryFile);
+                    newLibraryFile.delete();
+                }
+                if (!oldLibraryFile.renameTo(newLibraryFile)) {
+                    Slog.e(TAG, "Cannot rename native library directory "
+                            + oldLibraryFile.getPath() + " to " + newLibraryFile.getPath());
+                    return false;
+                }
+                libraryPath = newLibraryFile.getPath();
 
                 // Attempt to set permissions
                 if (!setPermissions()) {
@@ -6910,8 +6998,15 @@
             }
         }
 
+        private String getLibraryPathFromCodePath() {
+            return new File(mAppLibInstallDir, getApkName(getCodePath())).getPath();
+        }
+
         @Override
         String getNativeLibraryPath() {
+            if (libraryPath == null) {
+                libraryPath = getLibraryPathFromCodePath();
+            }
             return libraryPath;
         }
 
@@ -6937,6 +7032,15 @@
                     publicSourceFile.delete();
                 }
             }
+
+            if (libraryPath != null) {
+                File nativeLibraryFile = new File(libraryPath);
+                NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
+                if (!nativeLibraryFile.delete()) {
+                    Slog.w(TAG, "Couldn't delete native library directory " + libraryPath);
+                }
+            }
+
             return ret;
         }
 
@@ -8259,20 +8363,22 @@
                     if (conn.mContainerService == null) {
                         return;
                     }
-                    final File externalCacheDir = Environment
+
+                    final UserEnvironment userEnv = new UserEnvironment(curUser);
+                    final File externalCacheDir = userEnv
                             .getExternalStorageAppCacheDirectory(packageName);
                     try {
                         conn.mContainerService.clearDirectory(externalCacheDir.toString());
                     } catch (RemoteException e) {
                     }
                     if (allData) {
-                        final File externalDataDir = Environment
+                        final File externalDataDir = userEnv
                                 .getExternalStorageAppDataDirectory(packageName);
                         try {
                             conn.mContainerService.clearDirectory(externalDataDir.toString());
                         } catch (RemoteException e) {
                         }
-                        final File externalMediaDir = Environment
+                        final File externalMediaDir = userEnv
                                 .getExternalStorageAppMediaDirectory(packageName);
                         try {
                             conn.mContainerService.clearDirectory(externalMediaDir.toString());
@@ -9779,31 +9885,26 @@
                                     final String newNativePath = mp.targetArgs
                                             .getNativeLibraryPath();
 
-                                    try {
-                                        final File newNativeDir = new File(newNativePath);
+                                    final File newNativeDir = new File(newNativePath);
 
-                                        final String libParentDir = newNativeDir.getParentFile()
-                                                .getCanonicalPath();
-                                        if (newNativeDir.getParentFile().getCanonicalPath()
-                                                .equals(pkg.applicationInfo.dataDir)) {
-                                            if (mInstaller
-                                                    .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
-                                                returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
-                                            } else {
-                                                NativeLibraryHelper.copyNativeBinariesIfNeededLI(
-                                                        new File(newCodePath), newNativeDir);
-                                            }
-                                        } else {
+                                    if (!isForwardLocked(pkg) && !isExternal(pkg)) {
+                                        synchronized (mInstallLock) {
                                             if (mInstaller.linkNativeLibraryDirectory(
                                                     pkg.applicationInfo.dataDir, newNativePath) < 0) {
                                                 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
                                             }
                                         }
-                                    } catch (IOException e) {
-                                        returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
+                                        NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File(
+                                                newCodePath), newNativeDir);
+                                    } else {
+                                        synchronized (mInstallLock) {
+                                            if (mInstaller.linkNativeLibraryDirectory(
+                                                    pkg.applicationInfo.dataDir, newNativePath) < 0) {
+                                                returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+                                            }
+                                        }
                                     }
 
-
                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
                                         pkg.mPath = newCodePath;
                                         // Move dex files around
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index a13c16e..fc01f60 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -238,6 +238,18 @@
     }
 
     /**
+     * Check if we've hit the limit of how many users can be created.
+     */
+    private boolean isUserLimitReached() {
+        synchronized (mInstallLock) {
+            int nUsers = mUsers.size();
+            int userLimit = mContext.getResources().getInteger(
+                    com.android.internal.R.integer.config_multiuserMaximumUsers);
+            return nUsers >= userLimit;
+        }
+    }
+
+    /**
      * Enforces that only the system UID or root's UID or apps that have the
      * {@link android.Manifest.permission.MANAGE_USERS MANAGE_USERS}
      * permission can make certain calls to the UserManager.
@@ -281,7 +293,7 @@
      * cache it elsewhere.
      * @return the array of user ids.
      */
-    int[] getUserIds() {
+    public int[] getUserIds() {
         synchronized (mPackagesLock) {
             return mUserIds;
         }
@@ -522,6 +534,9 @@
     @Override
     public UserInfo createUser(String name, int flags) {
         checkManageUsersPermission("Only the system can create users");
+
+        if (isUserLimitReached()) return null;
+
         int userId = getNextAvailableId();
         UserInfo userInfo = new UserInfo(userId, name, null, flags);
         File userPath = new File(mBaseUserPath, Integer.toString(userId));
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 607ff39..3ef6d4c 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -183,12 +183,9 @@
         // We do not show the USB notification if the primary volume supports mass storage.
         // The legacy mass storage UI will be used instead.
         boolean massStorageSupported = false;
-        StorageManager storageManager = (StorageManager)
-                mContext.getSystemService(Context.STORAGE_SERVICE);
-        StorageVolume[] volumes = storageManager.getVolumeList();
-        if (volumes.length > 0) {
-            massStorageSupported = volumes[0].allowMassStorage();
-        }
+        final StorageManager storageManager = StorageManager.from(mContext);
+        final StorageVolume primary = storageManager.getPrimaryVolume();
+        massStorageSupported = primary != null && primary.allowMassStorage();
         mUseUsbNotification = !massStorageSupported;
 
         // make sure the ADB_ENABLED setting value matches the current state
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 5ff8a9b..aa18ee4 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -19,11 +19,13 @@
 import com.android.server.input.InputManagerService;
 import com.android.server.input.InputApplicationHandle;
 import com.android.server.input.InputWindowHandle;
+import com.android.server.wm.WindowManagerService.AllWindowsIterator;
 
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.Slog;
+import android.view.Display;
 import android.view.InputChannel;
 import android.view.KeyEvent;
 import android.view.WindowManager;
@@ -225,10 +227,11 @@
             addInputWindowHandleLw(mService.mFakeWindows.get(i).mWindowHandle);
         }
 
-        // TODO(multidisplay): Input only occurs on the default display.
-        final WindowList windows = mService.getDefaultWindowList();
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState child = windows.get(i);
+        // Add all windows on the default display.
+        final AllWindowsIterator iterator = mService.new AllWindowsIterator(
+                WindowManagerService.REVERSE_ITERATOR);
+        while (iterator.hasNext()) {
+            final WindowState child = iterator.next();
             final InputChannel inputChannel = child.mInputChannel;
             final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
             if (inputChannel == null || inputWindowHandle == null || child.mRemoved) {
@@ -243,15 +246,16 @@
             final boolean isVisible = child.isVisibleLw();
             final boolean hasWallpaper = (child == mService.mWallpaperTarget)
                     && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
+            final boolean onDefaultDisplay = (child.getDisplayId() == Display.DEFAULT_DISPLAY);
 
             // If there's a drag in progress and 'child' is a potential drop target,
             // make sure it's been told about the drag
-            if (inDrag && isVisible) {
+            if (inDrag && isVisible && onDefaultDisplay) {
                 mService.mDragState.sendDragStartedIfNeededLw(child);
             }
 
             if (universeBackground != null && !addedUniverse
-                    && child.mBaseLayer < aboveUniverseLayer) {
+                    && child.mBaseLayer < aboveUniverseLayer && onDefaultDisplay) {
                 final WindowState u = universeBackground.mWin;
                 if (u.mInputChannel != null && u.mInputWindowHandle != null) {
                     addInputWindowHandleLw(u.mInputWindowHandle, u, u.mAttrs.flags,
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index 7c7d4b1..8d2e2e8 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -48,6 +48,7 @@
     BlackFrame mExitingBlackFrame;
     BlackFrame mEnteringBlackFrame;
     int mWidth, mHeight;
+    int mExitAnimId, mEnterAnimId;
 
     int mOriginalRotation;
     int mOriginalWidth, mOriginalHeight;
@@ -188,9 +189,12 @@
     }
 
     public ScreenRotationAnimation(Context context, Display display, SurfaceSession session,
-            boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
+            boolean inTransaction, int originalWidth, int originalHeight, int originalRotation,
+            int exitAnim, int enterAnim) {
         mContext = context;
         mDisplay = display;
+        mExitAnimId = exitAnim;
+        mEnterAnimId = enterAnim;
 
         // Screenshot does NOT include rotation!
         if (originalRotation == Surface.ROTATION_90
@@ -375,58 +379,68 @@
                 + finalWidth + " finalHeight=" + finalHeight
                 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
 
-        switch (delta) {
-            case Surface.ROTATION_0:
-                mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
-                        com.android.internal.R.anim.screen_rotate_0_exit);
-                mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
-                        com.android.internal.R.anim.screen_rotate_0_enter);
-                if (USE_CUSTOM_BLACK_FRAME) {
-                    mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_0_frame);
-                }
-                break;
-            case Surface.ROTATION_90:
-                mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
-                        com.android.internal.R.anim.screen_rotate_plus_90_exit);
-                mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
-                        com.android.internal.R.anim.screen_rotate_plus_90_enter);
-                if (USE_CUSTOM_BLACK_FRAME) {
-                    mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_plus_90_frame);
-                }
-                break;
-            case Surface.ROTATION_180:
-                mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
-                        com.android.internal.R.anim.screen_rotate_180_exit);
-                mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
-                        com.android.internal.R.anim.screen_rotate_180_enter);
-                mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
-                        com.android.internal.R.anim.screen_rotate_180_frame);
-                break;
-            case Surface.ROTATION_270:
-                mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
-                        com.android.internal.R.anim.screen_rotate_minus_90_exit);
-                mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
-                        com.android.internal.R.anim.screen_rotate_minus_90_enter);
-                if (USE_CUSTOM_BLACK_FRAME) {
-                    mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_minus_90_frame);
-                }
-                break;
+        final boolean customAnim;
+        if (mExitAnimId != 0 && mEnterAnimId != 0) {
+            customAnim = true;
+            mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, mExitAnimId);
+            mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, mEnterAnimId);
+        } else {
+            customAnim = false;
+            switch (delta) {
+                case Surface.ROTATION_0:
+                    mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
+                            com.android.internal.R.anim.screen_rotate_0_exit);
+                    mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
+                            com.android.internal.R.anim.screen_rotate_0_enter);
+                    if (USE_CUSTOM_BLACK_FRAME) {
+                        mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
+                                com.android.internal.R.anim.screen_rotate_0_frame);
+                    }
+                    break;
+                case Surface.ROTATION_90:
+                    mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
+                            com.android.internal.R.anim.screen_rotate_plus_90_exit);
+                    mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
+                            com.android.internal.R.anim.screen_rotate_plus_90_enter);
+                    if (USE_CUSTOM_BLACK_FRAME) {
+                        mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
+                                com.android.internal.R.anim.screen_rotate_plus_90_frame);
+                    }
+                    break;
+                case Surface.ROTATION_180:
+                    mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
+                            com.android.internal.R.anim.screen_rotate_180_exit);
+                    mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
+                            com.android.internal.R.anim.screen_rotate_180_enter);
+                    if (USE_CUSTOM_BLACK_FRAME) {
+                        mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
+                                com.android.internal.R.anim.screen_rotate_180_frame);
+                    }
+                    break;
+                case Surface.ROTATION_270:
+                    mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
+                            com.android.internal.R.anim.screen_rotate_minus_90_exit);
+                    mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
+                            com.android.internal.R.anim.screen_rotate_minus_90_enter);
+                    if (USE_CUSTOM_BLACK_FRAME) {
+                        mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
+                                com.android.internal.R.anim.screen_rotate_minus_90_frame);
+                    }
+                    break;
+            }
         }
 
-        // Compute partial steps between original and final sizes.  These
-        // are used for the dimensions of the exiting and entering elements,
-        // so they are never stretched too significantly.
-        final int halfWidth = (finalWidth + mOriginalWidth) / 2;
-        final int halfHeight = (finalHeight + mOriginalHeight) / 2;
-
         // Initialize the animations.  This is a hack, redefining what "parent"
         // means to allow supplying the last and next size.  In this definition
         // "%p" is the original (let's call it "previous") size, and "%" is the
         // screen's current/new size.
         if (TWO_PHASE_ANIMATION && firstStart) {
+            // Compute partial steps between original and final sizes.  These
+            // are used for the dimensions of the exiting and entering elements,
+            // so they are never stretched too significantly.
+            final int halfWidth = (finalWidth + mOriginalWidth) / 2;
+            final int halfHeight = (finalHeight + mOriginalHeight) / 2;
+
             if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
             mStartEnterAnimation.initialize(finalWidth, finalHeight,
                     halfWidth, halfHeight);
@@ -510,7 +524,7 @@
             }
         }
 
-        if (mExitingBlackFrame == null) {
+        if (!customAnim && mExitingBlackFrame == null) {
             if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
                     WindowManagerService.TAG,
                     ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
@@ -540,7 +554,7 @@
             }
         }
 
-        if (false && mEnteringBlackFrame == null) {
+        if (customAnim && mEnteringBlackFrame == null) {
             if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
                     WindowManagerService.TAG,
                     ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index cdca8bc..b1e4f4b 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -434,6 +434,7 @@
 
     final float[] mTmpFloats = new float[9];
 
+    boolean mDisplayReady;
     boolean mSafeMode;
     boolean mDisplayEnabled = false;
     boolean mSystemBooted = false;
@@ -460,6 +461,7 @@
     boolean mDisplayFrozen = false;
     boolean mWaitingForConfig = false;
     boolean mWindowsFreezingScreen = false;
+    boolean mClientFreezingScreen = false;
     int mAppsFreezingScreen = 0;
     int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 
@@ -503,8 +505,6 @@
     final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
     final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
 
-    Display mDefaultDisplay;
-
     boolean mIsTouchDevice;
 
     final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
@@ -2085,7 +2085,7 @@
         long origId;
 
         synchronized(mWindowMap) {
-            if (mDefaultDisplay == null) {
+            if (!mDisplayReady) {
                 throw new IllegalStateException("Display has not been initialialized");
             }
 
@@ -3153,6 +3153,7 @@
         info.compatibilityScale = window.mGlobalScale;
         info.visible = window.isVisibleLw()
                 || info.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
+        info.layer = window.mLayer;
         window.getTouchableRegion(mTempRegion);
         mTempRegion.getBounds(info.touchableRegion);
         return info;
@@ -3916,7 +3917,7 @@
                 if (currentConfig.diff(mTempConfiguration) != 0) {
                     mWaitingForConfig = true;
                     getDefaultDisplayContent().layoutNeeded = true;
-                    startFreezingDisplayLocked(false);
+                    startFreezingDisplayLocked(false, 0, 0);
                     config = new Configuration(mTempConfiguration);
                 }
             }
@@ -4645,7 +4646,7 @@
                 wtoken.mAppAnimator.freezingScreen = true;
                 mAppsFreezingScreen++;
                 if (mAppsFreezingScreen == 1) {
-                    startFreezingDisplayLocked(false);
+                    startFreezingDisplayLocked(false, 0, 0);
                     mH.removeMessages(H.APP_FREEZE_TIMEOUT);
                     mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
                             5000);
@@ -5155,6 +5156,49 @@
     // -------------------------------------------------------------
 
     @Override
+    public void startFreezingScreen(int exitAnim, int enterAnim) {
+        if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
+                "startFreezingScreen()")) {
+            throw new SecurityException("Requires FREEZE_SCREEN permission");
+        }
+
+        synchronized(mWindowMap) {
+            if (!mClientFreezingScreen) {
+                mClientFreezingScreen = true;
+                final long origId = Binder.clearCallingIdentity();
+                try {
+                    startFreezingDisplayLocked(false, exitAnim, enterAnim);
+                    mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
+                    mH.sendMessageDelayed(mH.obtainMessage(H.CLIENT_FREEZE_TIMEOUT),
+                            5000);
+                } finally {
+                    Binder.restoreCallingIdentity(origId);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void stopFreezingScreen() {
+        if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
+                "stopFreezingScreen()")) {
+            throw new SecurityException("Requires FREEZE_SCREEN permission");
+        }
+
+        synchronized(mWindowMap) {
+            if (mClientFreezingScreen) {
+                mClientFreezingScreen = false;
+                final long origId = Binder.clearCallingIdentity();
+                try {
+                    stopFreezingDisplayLocked();
+                } finally {
+                    Binder.restoreCallingIdentity(origId);
+                }
+            }
+        }
+    }
+
+    @Override
     public void disableKeyguard(IBinder token, String tag) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
             != PackageManager.PERMISSION_GRANTED) {
@@ -5604,8 +5648,10 @@
                     ">>> OPEN TRANSACTION showStrictModeViolation");
             Surface.openTransaction();
             try {
+                // TODO(multi-display): support multiple displays
                 if (mStrictModeFlash == null) {
-                    mStrictModeFlash = new StrictModeFlash(mDefaultDisplay, mFxSession);
+                    mStrictModeFlash = new StrictModeFlash(
+                            getDefaultDisplayContent().getDisplay(), mFxSession);
                 }
                 mStrictModeFlash.setVisibility(on);
             } finally {
@@ -5718,7 +5764,7 @@
             }
 
             // The screenshot API does not apply the current screen rotation.
-            rot = mDefaultDisplay.getRotation();
+            rot = getDefaultDisplayContent().getDisplay().getRotation();
             int fw = frame.width();
             int fh = frame.height();
 
@@ -5946,7 +5992,7 @@
         mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT), 2000);
         mWaitingForConfig = true;
         getDefaultDisplayContent().layoutNeeded = true;
-        startFreezingDisplayLocked(inTransaction);
+        startFreezingDisplayLocked(inTransaction, 0, 0);
 
         // We need to update our screen size information to match the new
         // rotation.  Note that this is redundant with the later call to
@@ -6751,7 +6797,7 @@
     }
 
     boolean computeScreenConfigurationLocked(Configuration config) {
-        if (mDefaultDisplay == null) {
+        if (!mDisplayReady) {
             return false;
         }
 
@@ -6785,13 +6831,8 @@
         }
 
         if (config != null) {
-            int orientation = Configuration.ORIENTATION_SQUARE;
-            if (dw < dh) {
-                orientation = Configuration.ORIENTATION_PORTRAIT;
-            } else if (dw > dh) {
-                orientation = Configuration.ORIENTATION_LANDSCAPE;
-            }
-            config.orientation = orientation;
+            config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
+                    Configuration.ORIENTATION_LANDSCAPE;
         }
 
         // Update application display metrics.
@@ -6958,9 +6999,12 @@
             synchronized (mWindowMap) {
                 try {
                     if (mDragState == null) {
+                        // TODO(multi-display): support other displays
+                        final DisplayContent displayContent = getDefaultDisplayContent();
+                        final Display display = displayContent.getDisplay();
                         Surface surface = new Surface(session, "drag surface",
                                 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
-                        surface.setLayerStack(mDefaultDisplay.getLayerStack());
+                        surface.setLayerStack(display.getLayerStack());
                         if (SHOW_TRANSACTIONS) Slog.i(TAG, "  DRAG "
                                 + surface + ": CREATE");
                         outSurface.copyFrom(surface);
@@ -7102,26 +7146,28 @@
     }
 
     public void displayReady() {
-        WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
-        final Display display = wm.getDefaultDisplay();
-        displayReady(display.getDisplayId());
+        displayReady(Display.DEFAULT_DISPLAY);
 
         synchronized(mWindowMap) {
-            readForcedDisplaySizeAndDensityLocked(getDefaultDisplayContent());
+            final DisplayContent displayContent = getDefaultDisplayContent();
+            final Display display = displayContent.getDisplay();
+            readForcedDisplaySizeAndDensityLocked(displayContent);
 
-            mDefaultDisplay = display;
+            mDisplayReady = true;
             mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_TOUCHSCREEN);
+                    PackageManager.FEATURE_TOUCHSCREEN);
 
             mAnimator.initializeLocked(display.getLayerStack());
 
             final DisplayInfo displayInfo = getDefaultDisplayInfo();
-            mAnimator.setDisplayDimensions(displayInfo.logicalWidth, displayInfo.logicalHeight,
-                displayInfo.appWidth, displayInfo.appHeight);
+            mAnimator.setDisplayDimensions(
+                    displayInfo.logicalWidth, displayInfo.logicalHeight,
+                    displayInfo.appWidth, displayInfo.appHeight);
 
-            final DisplayContent displayContent = getDefaultDisplayContent();
-            mPolicy.setInitialDisplaySize(mDefaultDisplay, displayContent.mInitialDisplayWidth,
-                    displayContent.mInitialDisplayHeight, displayContent.mInitialDisplayDensity);
+            mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
+                    displayContent.mInitialDisplayWidth,
+                    displayContent.mInitialDisplayHeight,
+                    displayContent.mInitialDisplayDensity);
         }
 
         try {
@@ -7206,6 +7252,8 @@
         public static final int DO_DISPLAY_REMOVED = 32;
         public static final int DO_DISPLAY_CHANGED = 33;
 
+        public static final int CLIENT_FREEZE_TIMEOUT = 34;
+
         public static final int ANIMATOR_WHAT_OFFSET = 100000;
         public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
         public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2;
@@ -7532,6 +7580,16 @@
                     break;
                 }
 
+                case CLIENT_FREEZE_TIMEOUT: {
+                    synchronized (mWindowMap) {
+                        if (mClientFreezingScreen) {
+                            mClientFreezingScreen = false;
+                            stopFreezingDisplayLocked();
+                        }
+                    }
+                    break;
+                }
+
                 case SEND_NEW_CONFIGURATION: {
                     removeMessages(SEND_NEW_CONFIGURATION);
                     sendNewConfiguration();
@@ -7774,24 +7832,22 @@
         }
     }
 
-    public void setForcedDisplaySize(int displayId, int longDimen, int shortDimen) {
+    public void setForcedDisplaySize(int displayId, int width, int height) {
         synchronized(mWindowMap) {
+            // Set some sort of reasonable bounds on the size of the display that we
+            // will try to emulate.
+            final int MIN_WIDTH = 200;
+            final int MIN_HEIGHT = 200;
+            final int MAX_SCALE = 2;
             final DisplayContent displayContent = getDisplayContent(displayId);
-            int width, height;
-            if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
-                width = shortDimen < displayContent.mInitialDisplayWidth
-                        ? shortDimen : displayContent.mInitialDisplayWidth;
-                height = longDimen < displayContent.mInitialDisplayHeight
-                        ? longDimen : displayContent.mInitialDisplayHeight;
-            } else {
-                width = longDimen < displayContent.mInitialDisplayWidth
-                        ? longDimen : displayContent.mInitialDisplayWidth;
-                height = shortDimen < displayContent.mInitialDisplayHeight
-                        ? shortDimen : displayContent.mInitialDisplayHeight;
-            }
+
+            width = Math.min(Math.max(width, MIN_WIDTH),
+                    displayContent.mInitialDisplayWidth * MAX_SCALE);
+            height = Math.min(Math.max(height, MIN_HEIGHT),
+                    displayContent.mInitialDisplayHeight * MAX_SCALE);
             setForcedDisplaySizeLocked(displayContent, width, height);
-            Settings.Secure.putString(mContext.getContentResolver(),
-                    Settings.Secure.DISPLAY_SIZE_FORCED, width + "," + height);
+            Settings.Global.putString(mContext.getContentResolver(),
+                    Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
         }
     }
 
@@ -7802,6 +7858,7 @@
         }
         // TODO(multidisplay): For now rotations are only main screen.
         final DisplayContent displayContent = getDefaultDisplayContent();
+        final Display display = displayContent.getDisplay();
         if (displayContent.mBaseDisplayWidth < displayContent.mInitialDisplayWidth
                 || displayContent.mBaseDisplayHeight < displayContent.mInitialDisplayHeight) {
             int initW, initH, baseW, baseH;
@@ -7829,7 +7886,7 @@
             Rect inner = new Rect(0, 0, baseW, baseH);
             try {
                 mBlackFrame = new BlackFrame(mFxSession, outer, inner, MASK_LAYER,
-                        mDefaultDisplay.getLayerStack());
+                        display.getLayerStack());
             } catch (Surface.OutOfResourcesException e) {
             }
         }
@@ -7837,8 +7894,8 @@
 
     private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
         boolean changed = false;
-        final String sizeStr = Settings.Secure.getString(mContext.getContentResolver(),
-                Settings.Secure.DISPLAY_SIZE_FORCED);
+        final String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.DISPLAY_SIZE_FORCED);
         if (sizeStr != null && sizeStr.length() > 0) {
             final int pos = sizeStr.indexOf(',');
             if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
@@ -7859,8 +7916,8 @@
                 }
             }
         }
-        final String densityStr = Settings.Secure.getString(mContext.getContentResolver(),
-                Settings.Secure.DISPLAY_DENSITY_FORCED);
+        final String densityStr = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.DISPLAY_DENSITY_FORCED);
         if (densityStr != null && densityStr.length() > 0) {
             int density;
             try {
@@ -7895,8 +7952,8 @@
             final DisplayContent displayContent = getDisplayContent(displayId);
             setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
                     displayContent.mInitialDisplayHeight);
-            Settings.Secure.putString(mContext.getContentResolver(),
-                    Settings.Secure.DISPLAY_SIZE_FORCED, "");
+            Settings.Global.putString(mContext.getContentResolver(),
+                    Settings.Global.DISPLAY_SIZE_FORCED, "");
         }
     }
 
@@ -7904,8 +7961,8 @@
         synchronized(mWindowMap) {
             final DisplayContent displayContent = getDisplayContent(displayId);
             setForcedDisplayDensityLocked(displayContent, density);
-            Settings.Secure.putString(mContext.getContentResolver(),
-                    Settings.Secure.DISPLAY_DENSITY_FORCED, Integer.toString(density));
+            Settings.Global.putString(mContext.getContentResolver(),
+                    Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
         }
     }
 
@@ -7929,8 +7986,10 @@
 
     private void reconfigureDisplayLocked(DisplayContent displayContent) {
         // TODO: Multidisplay: for now only use with default display.
-        mPolicy.setInitialDisplaySize(mDefaultDisplay, displayContent.mBaseDisplayWidth,
-                displayContent.mBaseDisplayHeight, displayContent.mBaseDisplayDensity);
+        mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
+                displayContent.mBaseDisplayWidth,
+                displayContent.mBaseDisplayHeight,
+                displayContent.mBaseDisplayDensity);
 
         displayContent.layoutNeeded = true;
 
@@ -7945,7 +8004,7 @@
 
         if (configChanged) {
             mWaitingForConfig = true;
-            startFreezingDisplayLocked(false);
+            startFreezingDisplayLocked(false, 0, 0);
             mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
         }
 
@@ -8154,7 +8213,7 @@
             return;
         }
         
-        if (mDefaultDisplay == null) {
+        if (!mDisplayReady) {
             // Not yet initialized, nothing to do.
             return;
         }
@@ -8600,11 +8659,14 @@
                 Rect dirty = new Rect(0, 0, mNextAppTransitionThumbnail.getWidth(),
                         mNextAppTransitionThumbnail.getHeight());
                 try {
+                    // TODO(multi-display): support other displays
+                    final DisplayContent displayContent = getDefaultDisplayContent();
+                    final Display display = displayContent.getDisplay();
                     Surface surface = new Surface(mFxSession,
                             "thumbnail anim",
                             dirty.width(), dirty.height(),
                             PixelFormat.TRANSLUCENT, Surface.HIDDEN);
-                    surface.setLayerStack(mDefaultDisplay.getLayerStack());
+                    surface.setLayerStack(display.getLayerStack());
                     topOpeningApp.mAppAnimator.thumbnail = surface;
                     if (SHOW_TRANSACTIONS) Slog.i(TAG, "  THUMBNAIL "
                             + surface + ": CREATE");
@@ -9852,12 +9914,13 @@
         return result;
     }
 
-    private void startFreezingDisplayLocked(boolean inTransaction) {
+    private void startFreezingDisplayLocked(boolean inTransaction,
+            int exitAnim, int enterAnim) {
         if (mDisplayFrozen) {
             return;
         }
 
-        if (mDefaultDisplay == null || !mPolicy.isScreenOnFully()) {
+        if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
             // No need to freeze the screen before the system is ready or if
             // the screen is off.
             return;
@@ -9889,10 +9952,13 @@
             }
 
             // TODO(multidisplay): rotation on main screen only.
-            DisplayInfo displayInfo = getDefaultDisplayContent().getDisplayInfo();
+            final DisplayContent displayContent = getDefaultDisplayContent();
+            final Display display = displayContent.getDisplay();
+            final DisplayInfo displayInfo = displayContent.getDisplayInfo();
             mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
-                    mDefaultDisplay, mFxSession, inTransaction, displayInfo.logicalWidth,
-                    displayInfo.logicalHeight, mDefaultDisplay.getRotation());
+                    display, mFxSession, inTransaction, displayInfo.logicalWidth,
+                    displayInfo.logicalHeight, display.getRotation(),
+                    exitAnim, enterAnim);
         }
     }
 
@@ -9901,16 +9967,19 @@
             return;
         }
 
-        if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
+        if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
+                || mClientFreezingScreen) {
             if (DEBUG_ORIENTATION) Slog.d(TAG,
                 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
                 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
-                + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen);
+                + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
+                + ", mClientFreezingScreen=" + mClientFreezingScreen);
             return;
         }
         
         mDisplayFrozen = false;
         mH.removeMessages(H.APP_FREEZE_TIMEOUT);
+        mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
         if (PROFILE_ORIENTATION) {
             Debug.stopMethodTracing();
         }
@@ -10003,8 +10072,8 @@
             if (line != null) {
                 String[] toks = line.split("%");
                 if (toks != null && toks.length > 0) {
-                    mWatermark =
-                            new Watermark(mDefaultDisplay, mRealDisplayMetrics, mFxSession, toks);
+                    mWatermark = new Watermark(getDefaultDisplayContent().getDisplay(),
+                            mRealDisplayMetrics, mFxSession, toks);
                 }
             }
         } catch (FileNotFoundException e) {
@@ -10372,7 +10441,7 @@
             }
         }
         pw.println();
-        if (mDefaultDisplay != null) {
+        if (mDisplayReady) {
             DisplayContentsIterator dCIterator = new DisplayContentsIterator();
             while (dCIterator.hasNext()) {
                 dCIterator.next().dump(pw);
@@ -10431,9 +10500,10 @@
             }
             pw.print("  mTransactionSequence="); pw.println(mTransactionSequence);
             pw.print("  mDisplayFrozen="); pw.print(mDisplayFrozen);
-                    pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
-                    pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
-                    pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
+                    pw.print(" windows="); pw.print(mWindowsFreezingScreen);
+                    pw.print(" client="); pw.print(mClientFreezingScreen);
+                    pw.print(" apps="); pw.print(mAppsFreezingScreen);
+                    pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
             pw.print("  mRotation="); pw.print(mRotation);
                     pw.print(" mAltOrientation="); pw.println(mAltOrientation);
             pw.print("  mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
@@ -10744,7 +10814,7 @@
         }
     }
 
-    boolean REVERSE_ITERATOR = true;
+    final static boolean REVERSE_ITERATOR = true;
     class AllWindowsIterator implements Iterator<WindowState> {
         private DisplayContent mDisplayContent;
         private DisplayContentsIterator mDisplayContentsIterator;
@@ -10804,9 +10874,7 @@
     }
 
     public DisplayContent getDefaultDisplayContent() {
-        final int displayId = mDefaultDisplay == null
-                ? Display.DEFAULT_DISPLAY : mDefaultDisplay.getDisplayId();
-        return getDisplayContent(displayId);
+        return getDisplayContent(Display.DEFAULT_DISPLAY);
     }
 
     public WindowList getDefaultWindowList() {
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 5e36bf8..319cacd 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -993,7 +993,8 @@
 static void nativeSetDisplayViewport(JNIEnv* env, jclass clazz, jint ptr, jboolean external,
         jint displayId, jint orientation,
         jint logicalLeft, jint logicalTop, jint logicalRight, jint logicalBottom,
-        jint physicalLeft, jint physicalTop, jint physicalRight, jint physicalBottom) {
+        jint physicalLeft, jint physicalTop, jint physicalRight, jint physicalBottom,
+        jint deviceWidth, jint deviceHeight) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     DisplayViewport v;
@@ -1007,6 +1008,8 @@
     v.physicalTop = physicalTop;
     v.physicalRight = physicalRight;
     v.physicalBottom = physicalBottom;
+    v.deviceWidth = deviceWidth;
+    v.deviceHeight = deviceHeight;
     im->setDisplayViewport(external, v);
 }
 
@@ -1288,7 +1291,7 @@
             (void*) nativeInit },
     { "nativeStart", "(I)V",
             (void*) nativeStart },
-    { "nativeSetDisplayViewport", "(IZIIIIIIIIII)V",
+    { "nativeSetDisplayViewport", "(IZIIIIIIIIIIII)V",
             (void*) nativeSetDisplayViewport },
     { "nativeGetScanCodeState", "(IIII)I",
             (void*) nativeGetScanCodeState },
diff --git a/services/jni/com_android_server_input_InputWindowHandle.cpp b/services/jni/com_android_server_input_InputWindowHandle.cpp
index 01fb781..6692994 100644
--- a/services/jni/com_android_server_input_InputWindowHandle.cpp
+++ b/services/jni/com_android_server_input_InputWindowHandle.cpp
@@ -52,6 +52,7 @@
     jfieldID ownerPid;
     jfieldID ownerUid;
     jfieldID inputFeatures;
+    jfieldID displayId;
 } gInputWindowHandleClassInfo;
 
 static Mutex gHandleMutex;
@@ -151,6 +152,8 @@
             gInputWindowHandleClassInfo.ownerUid);
     mInfo->inputFeatures = env->GetIntField(obj,
             gInputWindowHandleClassInfo.inputFeatures);
+    mInfo->displayId = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.displayId);
 
     env->DeleteLocalRef(obj);
     return true;
@@ -291,6 +294,9 @@
 
     GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
             "inputFeatures", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
+            "displayId", "I");
     return 0;
 }
 
diff --git a/telephony/java/com/android/internal/telephony/IccCardConstants.java b/telephony/java/com/android/internal/telephony/IccCardConstants.java
index 4d1eb3f..236bb2f 100644
--- a/telephony/java/com/android/internal/telephony/IccCardConstants.java
+++ b/telephony/java/com/android/internal/telephony/IccCardConstants.java
@@ -47,10 +47,13 @@
     /* PERM_DISABLED means ICC is permanently disabled due to puk fails */
     public static final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
 
-    /*
-      UNKNOWN is a transient state, for example, after uesr inputs ICC pin under
-      PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it
-      turns to READY
+    /**
+     * This is combination of IccCardStatus.CardState and IccCardApplicationStatus.AppState
+     * for external apps (like PhoneApp) to use
+     *
+     * UNKNOWN is a transient state, for example, after user inputs ICC pin under
+     * PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it
+     * turns to READY
      */
     public enum State {
         UNKNOWN,
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blur25.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blur25.java
index 697bbb1..9728c12 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blur25.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blur25.java
@@ -21,14 +21,16 @@
 import android.renderscript.Allocation;
 import android.renderscript.Element;
 import android.renderscript.RenderScript;
-import android.renderscript.Script;
-import android.renderscript.ScriptC;
+import android.renderscript.ScriptIntrinsicBlur;
 import android.renderscript.Type;
 import android.util.Log;
 import android.widget.SeekBar;
 import android.widget.TextView;
 
 public class Blur25 extends TestBase {
+    private boolean mUseIntrinsic = false;
+    private ScriptIntrinsicBlur mIntrinsic;
+
     private int MAX_RADIUS = 25;
     private ScriptC_threshold mScript;
     private ScriptC_vertical_blur mScriptVBlur;
@@ -39,6 +41,10 @@
     private Allocation mScratchPixelsAllocation2;
 
 
+    public Blur25(boolean useIntrinsic) {
+        mUseIntrinsic = useIntrinsic;
+    }
+
     public boolean onBar1Setup(SeekBar b, TextView t) {
         t.setText("Radius");
         b.setProgress(100);
@@ -67,40 +73,59 @@
         int width = mInPixelsAllocation.getType().getX();
         int height = mInPixelsAllocation.getType().getY();
 
-        Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS));
-        tb.setX(width);
-        tb.setY(height);
-        mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
-        mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());
+        if (mUseIntrinsic) {
+            mIntrinsic = ScriptIntrinsicBlur.create(mRS, Element.U8_4(mRS));
+            mIntrinsic.setRadius(25.f);
+            mIntrinsic.setInput(mInPixelsAllocation);
+        } else {
 
-        mScriptVBlur = new ScriptC_vertical_blur(mRS, res, R.raw.vertical_blur);
-        mScriptHBlur = new ScriptC_horizontal_blur(mRS, res, R.raw.horizontal_blur);
+            Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS));
+            tb.setX(width);
+            tb.setY(height);
+            mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
+            mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());
 
-        mScript = new ScriptC_threshold(mRS, res, R.raw.threshold);
-        mScript.set_width(width);
-        mScript.set_height(height);
-        mScript.set_radius(mRadius);
+            mScriptVBlur = new ScriptC_vertical_blur(mRS, res, R.raw.vertical_blur);
+            mScriptHBlur = new ScriptC_horizontal_blur(mRS, res, R.raw.horizontal_blur);
 
-        mScriptVBlur.invoke_setSaturation(mSaturation);
+            mScript = new ScriptC_threshold(mRS, res, R.raw.threshold);
+            mScript.set_width(width);
+            mScript.set_height(height);
+            mScript.set_radius(mRadius);
 
-        mScript.bind_InPixel(mInPixelsAllocation);
-        mScript.bind_OutPixel(mOutPixelsAllocation);
-        mScript.bind_ScratchPixel1(mScratchPixelsAllocation1);
-        mScript.bind_ScratchPixel2(mScratchPixelsAllocation2);
+            mScriptVBlur.invoke_setSaturation(mSaturation);
 
-        mScript.set_vBlurScript(mScriptVBlur);
-        mScript.set_hBlurScript(mScriptHBlur);
+            mScript.bind_InPixel(mInPixelsAllocation);
+            mScript.bind_OutPixel(mOutPixelsAllocation);
+            mScript.bind_ScratchPixel1(mScratchPixelsAllocation1);
+            mScript.bind_ScratchPixel2(mScratchPixelsAllocation2);
+
+            mScript.set_vBlurScript(mScriptVBlur);
+            mScript.set_hBlurScript(mScriptHBlur);
+        }
     }
 
     public void runTest() {
-        mScript.invoke_filter();
+        if (mUseIntrinsic) {
+            mIntrinsic.forEach(mOutPixelsAllocation);
+        } else {
+            mScript.invoke_filter();
+        }
     }
 
     public void setupBenchmark() {
-        mScript.set_radius(MAX_RADIUS);
+        if (mUseIntrinsic) {
+            mIntrinsic.setRadius(MAX_RADIUS);
+        } else {
+            mScript.set_radius(MAX_RADIUS);
+        }
     }
 
     public void exitBenchmark() {
-        mScript.set_radius(mRadius);
+        if (mUseIntrinsic) {
+            mIntrinsic.setRadius(mRadius);
+        } else {
+            mScript.set_radius(mRadius);
+        }
     }
 }
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Convolve5x5.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Convolve5x5.java
new file mode 100644
index 0000000..b3914d1
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Convolve5x5.java
@@ -0,0 +1,76 @@
+/*
+ * 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.rs.image;
+
+import java.lang.Math;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScript;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
+import android.renderscript.ScriptGroup;
+import android.renderscript.ScriptIntrinsicConvolve5x5;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class Convolve5x5 extends TestBase {
+    private ScriptC_convolve5x5 mScript;
+    private ScriptIntrinsicConvolve5x5 mIntrinsic;
+
+    private int mWidth;
+    private int mHeight;
+    private boolean mUseIntrinsic;
+
+    public Convolve5x5(boolean useIntrinsic) {
+        mUseIntrinsic = useIntrinsic;
+    }
+
+    public void createTest(android.content.res.Resources res) {
+        mWidth = mInPixelsAllocation.getType().getX();
+        mHeight = mInPixelsAllocation.getType().getY();
+
+        float f[] = new float[25];
+        f[0] = 0.012f; f[1] = 0.025f; f[2] = 0.031f; f[3] = 0.025f; f[4] = 0.012f;
+        f[5] = 0.025f; f[6] = 0.057f; f[7] = 0.075f; f[8] = 0.057f; f[9] = 0.025f;
+        f[10]= 0.031f; f[11]= 0.075f; f[12]= 0.095f; f[13]= 0.075f; f[14]= 0.031f;
+        f[15]= 0.025f; f[16]= 0.057f; f[17]= 0.075f; f[18]= 0.057f; f[19]= 0.025f;
+        f[20]= 0.012f; f[21]= 0.025f; f[22]= 0.031f; f[23]= 0.025f; f[24]= 0.012f;
+
+        if (mUseIntrinsic) {
+            mIntrinsic = ScriptIntrinsicConvolve5x5.create(mRS, Element.U8_4(mRS));
+            mIntrinsic.setCoefficients(f);
+            mIntrinsic.setInput(mInPixelsAllocation);
+        } else {
+            mScript = new ScriptC_convolve5x5(mRS, res, R.raw.convolve5x5);
+            mScript.set_gCoeffs(f);
+            mScript.set_gIn(mInPixelsAllocation);
+            mScript.set_gWidth(mWidth);
+            mScript.set_gHeight(mHeight);
+        }
+    }
+
+    public void runTest() {
+        if (mUseIntrinsic) {
+            mIntrinsic.forEach(mOutPixelsAllocation);
+        } else {
+            mScript.forEach_root(mOutPixelsAllocation);
+        }
+    }
+
+}
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/CrossProcess.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/CrossProcess.java
new file mode 100644
index 0000000..b9e3524
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/CrossProcess.java
@@ -0,0 +1,63 @@
+/*
+ * 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.rs.image;
+
+import java.lang.Math;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.ScriptIntrinsicLUT;
+import android.util.Log;
+
+public class CrossProcess extends TestBase {
+    private ScriptIntrinsicLUT mIntrinsic;
+
+    public void createTest(android.content.res.Resources res) {
+        mIntrinsic = ScriptIntrinsicLUT.create(mRS, Element.U8_4(mRS));
+        for (int ct=0; ct < 256; ct++) {
+            float f = ((float)ct) / 255.f;
+
+            float r = f;
+            if (r < 0.5f) {
+                r = 4.0f * r * r * r;
+            } else {
+                r = 1.0f - r;
+                r = 1.0f - (4.0f * r * r * r);
+            }
+            mIntrinsic.setRed(ct, (int)(r * 255.f + 0.5f));
+
+            float g = f;
+            if (g < 0.5f) {
+                g = 2.0f * g * g;
+            } else {
+                g = 1.0f - g;
+                g = 1.0f - (2.0f * g * g);
+            }
+            mIntrinsic.setGreen(ct, (int)(g * 255.f + 0.5f));
+
+            float b = f * 0.5f + 0.25f;
+            mIntrinsic.setBlue(ct, (int)(b * 255.f + 0.5f));
+        }
+
+    }
+
+    public void runTest() {
+        mIntrinsic.forEach(mInPixelsAllocation, mOutPixelsAllocation);
+    }
+
+}
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 37577eb..7b84355 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -135,62 +135,74 @@
             mTest = new LevelsV4(true, true);
             break;
         case 4:
-            mTest = new Blur25();
+            mTest = new Blur25(false);
             break;
         case 5:
-            mTest = new Greyscale();
+            mTest = new Blur25(true);
             break;
         case 6:
-            mTest = new Grain();
+            mTest = new Greyscale();
             break;
         case 7:
-            mTest = new Fisheye(false, false);
+            mTest = new Grain();
             break;
         case 8:
-            mTest = new Fisheye(false, true);
+            mTest = new Fisheye(false, false);
             break;
         case 9:
-            mTest = new Fisheye(true, false);
+            mTest = new Fisheye(false, true);
             break;
         case 10:
-            mTest = new Fisheye(true, true);
+            mTest = new Fisheye(true, false);
             break;
         case 11:
-            mTest = new Vignette(false, false);
+            mTest = new Fisheye(true, true);
             break;
         case 12:
-            mTest = new Vignette(false, true);
+            mTest = new Vignette(false, false);
             break;
         case 13:
-            mTest = new Vignette(true, false);
+            mTest = new Vignette(false, true);
             break;
         case 14:
-            mTest = new Vignette(true, true);
+            mTest = new Vignette(true, false);
             break;
         case 15:
-            mTest = new GroupTest(false);
+            mTest = new Vignette(true, true);
             break;
         case 16:
-            mTest = new GroupTest(true);
+            mTest = new GroupTest(false);
             break;
         case 17:
-            mTest = new Convolve3x3(false);
+            mTest = new GroupTest(true);
             break;
         case 18:
-            mTest = new Convolve3x3(true);
+            mTest = new Convolve3x3(false);
             break;
         case 19:
-            mTest = new ColorMatrix(false, false);
+            mTest = new Convolve3x3(true);
             break;
         case 20:
-            mTest = new ColorMatrix(true, false);
+            mTest = new ColorMatrix(false, false);
             break;
         case 21:
-            mTest = new ColorMatrix(true, true);
+            mTest = new ColorMatrix(true, false);
             break;
         case 22:
+            mTest = new ColorMatrix(true, true);
+            break;
+        case 23:
             mTest = new Copy();
             break;
+        case 24:
+            mTest = new CrossProcess();
+            break;
+        case 25:
+            mTest = new Convolve5x5(false);
+            break;
+        case 26:
+            mTest = new Convolve5x5(true);
+            break;
         }
 
         mTest.createBaseTest(this, mBitmapIn);
@@ -203,30 +215,34 @@
     }
 
     void setupTests() {
-        mTestNames = new String[23];
+        mTestNames = new String[27];
         mTestNames[0] = "Levels Vec3 Relaxed";
         mTestNames[1] = "Levels Vec4 Relaxed";
         mTestNames[2] = "Levels Vec3 Full";
         mTestNames[3] = "Levels Vec4 Full";
         mTestNames[4] = "Blur radius 25";
-        mTestNames[5] = "Greyscale";
-        mTestNames[6] = "Grain";
-        mTestNames[7] = "Fisheye Full";
-        mTestNames[8] = "Fisheye Relaxed";
-        mTestNames[9] = "Fisheye Approximate Full";
-        mTestNames[10] = "Fisheye Approximate Relaxed";
-        mTestNames[11] = "Vignette Full";
-        mTestNames[12] = "Vignette Relaxed";
-        mTestNames[13] = "Vignette Approximate Full";
-        mTestNames[14] = "Vignette Approximate Relaxed";
-        mTestNames[15] = "Group Test (emulated)";
-        mTestNames[16] = "Group Test (native)";
-        mTestNames[17] = "Convolve 3x3";
-        mTestNames[18] = "Intrinsics Convolve 3x3";
-        mTestNames[19] = "ColorMatrix";
-        mTestNames[20] = "Intrinsics ColorMatrix";
-        mTestNames[21] = "Intrinsics ColorMatrix Grey";
-        mTestNames[22] = "Copy";
+        mTestNames[5] = "Intrinsic Blur radius 25";
+        mTestNames[6] = "Greyscale";
+        mTestNames[7] = "Grain";
+        mTestNames[8] = "Fisheye Full";
+        mTestNames[9] = "Fisheye Relaxed";
+        mTestNames[10] = "Fisheye Approximate Full";
+        mTestNames[11] = "Fisheye Approximate Relaxed";
+        mTestNames[12] = "Vignette Full";
+        mTestNames[13] = "Vignette Relaxed";
+        mTestNames[14] = "Vignette Approximate Full";
+        mTestNames[15] = "Vignette Approximate Relaxed";
+        mTestNames[16] = "Group Test (emulated)";
+        mTestNames[17] = "Group Test (native)";
+        mTestNames[18] = "Convolve 3x3";
+        mTestNames[19] = "Intrinsics Convolve 3x3";
+        mTestNames[20] = "ColorMatrix";
+        mTestNames[21] = "Intrinsics ColorMatrix";
+        mTestNames[22] = "Intrinsics ColorMatrix Grey";
+        mTestNames[23] = "Copy";
+        mTestNames[24] = "CrossProcess (using LUT)";
+        mTestNames[25] = "Convolve 5x5";
+        mTestNames[26] = "Intrinsics Convolve 5x5";
         mTestSpinner.setAdapter(new ArrayAdapter<String>(
             this, R.layout.spinner_layout, mTestNames));
     }
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve5x5.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve5x5.rs
new file mode 100644
index 0000000..fe6cf31
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve5x5.rs
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image)
+#pragma rs_fp_relaxed
+
+int32_t gWidth;
+int32_t gHeight;
+rs_allocation gIn;
+
+float gCoeffs[25];
+
+void root(uchar4 *out, uint32_t x, uint32_t y) {
+    uint32_t x0 = max((int32_t)x-2, 0);
+    uint32_t x1 = max((int32_t)x-1, 0);
+    uint32_t x2 = x;
+    uint32_t x3 = min((int32_t)x+1, gWidth-1);
+    uint32_t x4 = min((int32_t)x+2, gWidth-1);
+
+    uint32_t y0 = max((int32_t)y-2, 0);
+    uint32_t y1 = max((int32_t)y-1, 0);
+    uint32_t y2 = y;
+    uint32_t y3 = min((int32_t)y+1, gHeight-1);
+    uint32_t y4 = min((int32_t)y+2, gHeight-1);
+
+    float4 p0 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x0, y0))[0]) * gCoeffs[0]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y0))[0]) * gCoeffs[1]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y0))[0]) * gCoeffs[2]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x3, y0))[0]) * gCoeffs[3]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x4, y0))[0]) * gCoeffs[4];
+
+    float4 p1 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x0, y1))[0]) * gCoeffs[5]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y1))[0]) * gCoeffs[6]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y1))[0]) * gCoeffs[7]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x3, y1))[0]) * gCoeffs[8]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x4, y1))[0]) * gCoeffs[9];
+
+    float4 p2 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x0, y2))[0]) * gCoeffs[10]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y2))[0]) * gCoeffs[11]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y2))[0]) * gCoeffs[12]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x3, y2))[0]) * gCoeffs[13]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x4, y2))[0]) * gCoeffs[14];
+
+    float4 p3 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x0, y3))[0]) * gCoeffs[15]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y3))[0]) * gCoeffs[16]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y3))[0]) * gCoeffs[17]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x3, y3))[0]) * gCoeffs[18]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x4, y3))[0]) * gCoeffs[19];
+
+    float4 p4 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x0, y4))[0]) * gCoeffs[20]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y4))[0]) * gCoeffs[21]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y4))[0]) * gCoeffs[22]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x3, y4))[0]) * gCoeffs[23]
+              + convert_float4(((uchar4 *)rsGetElementAt(gIn, x4, y4))[0]) * gCoeffs[24];
+
+    p0 = clamp(p0 + p1 + p2 + p3 + p4, 0.f, 255.f);
+    *out = convert_uchar4(p0);
+}
+
+
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 5d64e8a..b8d21f3 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
@@ -107,6 +107,16 @@
     }
 
     @Override
+    public void startFreezingScreen(int exitAnim, int enterAnim) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void stopFreezingScreen() {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
     public void disableKeyguard(IBinder arg0, String arg1) throws RemoteException {
         // TODO Auto-generated method stub
 
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 3e20756..9977419 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -28,6 +28,10 @@
 public class ScanResult implements Parcelable {
     /** The network name. */
     public String SSID;
+
+    /** Ascii encoded SSID. This will replace SSID when we deprecate it. @hide */
+    public WifiSsid wifiSsid;
+
     /** The address of the access point. */
     public String BSSID;
     /**
@@ -52,15 +56,11 @@
      */
      public long timestamp;
 
-    /**
-     * We'd like to obtain the following attributes,
-     * but they are not reported via the socket
-     * interface, even though they are known
-     * internally by wpa_supplicant.
-     * {@hide}
-     */
-    public ScanResult(String SSID, String BSSID, String caps, int level, int frequency, long tsf) {
-        this.SSID = SSID;
+    /** {@hide} */
+    public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
+            long tsf) {
+        this.wifiSsid = wifiSsid;
+        this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
         this.BSSID = BSSID;
         this.capabilities = caps;
         this.level = level;
@@ -68,9 +68,11 @@
         this.timestamp = tsf;
     }
 
+
     /** copy constructor {@hide} */
     public ScanResult(ScanResult source) {
         if (source != null) {
+            wifiSsid = source.wifiSsid;
             SSID = source.SSID;
             BSSID = source.BSSID;
             capabilities = source.capabilities;
@@ -86,7 +88,7 @@
         String none = "<none>";
 
         sb.append("SSID: ").
-            append(SSID == null ? none : SSID).
+            append(wifiSsid == null ? WifiSsid.NONE : wifiSsid).
             append(", BSSID: ").
             append(BSSID == null ? none : BSSID).
             append(", capabilities: ").
@@ -108,7 +110,12 @@
 
     /** Implement the Parcelable interface {@hide} */
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(SSID);
+        if (wifiSsid != null) {
+            dest.writeInt(1);
+            wifiSsid.writeToParcel(dest, flags);
+        } else {
+            dest.writeInt(0);
+        }
         dest.writeString(BSSID);
         dest.writeString(capabilities);
         dest.writeInt(level);
@@ -120,8 +127,12 @@
     public static final Creator<ScanResult> CREATOR =
         new Creator<ScanResult>() {
             public ScanResult createFromParcel(Parcel in) {
+                WifiSsid wifiSsid = null;
+                if (in.readInt() == 1) {
+                    wifiSsid = WifiSsid.CREATOR.createFromParcel(in);
+                }
                 return new ScanResult(
-                    in.readString(),
+                    wifiSsid,
                     in.readString(),
                     in.readString(),
                     in.readInt(),
diff --git a/wifi/java/android/net/wifi/StateChangeResult.java b/wifi/java/android/net/wifi/StateChangeResult.java
index b15c4a6..c334b91 100644
--- a/wifi/java/android/net/wifi/StateChangeResult.java
+++ b/wifi/java/android/net/wifi/StateChangeResult.java
@@ -23,15 +23,16 @@
  * @hide
  */
 public class StateChangeResult {
-    StateChangeResult(int networkId, String SSID, String BSSID, SupplicantState state) {
+    StateChangeResult(int networkId, WifiSsid wifiSsid, String BSSID,
+            SupplicantState state) {
         this.state = state;
-        this.SSID = SSID;
+        this.wifiSsid= wifiSsid;
         this.BSSID = BSSID;
         this.networkId = networkId;
     }
 
     int networkId;
-    String SSID;
+    WifiSsid wifiSsid;
     String BSSID;
     SupplicantState state;
 }
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index a2332e3..84506b6 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -1318,7 +1318,13 @@
 
         value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.ssidVarName);
         if (!TextUtils.isEmpty(value)) {
-            config.SSID = value;
+            if (value.charAt(0) != '"') {
+                config.SSID = "\"" + WifiSsid.createFromHex(value).toString() + "\"";
+                //TODO: convert a hex string that is not UTF-8 decodable to a P-formatted
+                //supplicant string
+            } else {
+                config.SSID = value;
+            }
         } else {
             config.SSID = null;
         }
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 0a846fd..c4fe1b4 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -524,6 +524,27 @@
     }
     */
 
+    /** {@hide} */
+    public String getPrintableSsid() {
+        if (SSID == null) return "";
+        final int length = SSID.length();
+        if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') {
+            return SSID.substring(1, length - 1);
+        }
+
+        /** The ascii-encoded string format is P"<ascii-encoded-string>"
+         * The decoding is implemented in the supplicant for a newly configured
+         * network.
+         */
+        if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') &&
+                (SSID.charAt(length-1) == '"')) {
+            WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(
+                    SSID.substring(2, length - 1));
+            return wifiSsid.toString();
+        }
+        return SSID;
+    }
+
     private static BitSet readBitSet(Parcel src) {
         int cardinality = src.readInt();
 
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 1f1cfdd..05db571 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -20,6 +20,7 @@
 import android.os.Parcel;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkUtils;
+import android.text.TextUtils;
 
 import java.net.InetAddress;
 import java.net.Inet6Address;
@@ -31,6 +32,7 @@
  * is in the process of being set up.
  */
 public class WifiInfo implements Parcelable {
+    private static final String TAG = "WifiInfo";
     /**
      * This is the map described in the Javadoc comment above. The positions
      * of the elements of the array must correspond to the ordinal values
@@ -57,7 +59,7 @@
 
     private SupplicantState mSupplicantState;
     private String mBSSID;
-    private String mSSID;
+    private WifiSsid mWifiSsid;
     private int mNetworkId;
     private boolean mHiddenSSID;
     /** Received Signal Strength Indicator */
@@ -77,7 +79,7 @@
     private boolean mMeteredHint;
 
     WifiInfo() {
-        mSSID = null;
+        mWifiSsid = null;
         mBSSID = null;
         mNetworkId = -1;
         mSupplicantState = SupplicantState.UNINITIALIZED;
@@ -94,7 +96,7 @@
         if (source != null) {
             mSupplicantState = source.mSupplicantState;
             mBSSID = source.mBSSID;
-            mSSID = source.mSSID;
+            mWifiSsid = source.mWifiSsid;
             mNetworkId = source.mNetworkId;
             mHiddenSSID = source.mHiddenSSID;
             mRssi = source.mRssi;
@@ -105,21 +107,34 @@
         }
     }
 
-    void setSSID(String SSID) {
-        mSSID = SSID;
+    void setSSID(WifiSsid wifiSsid) {
+        mWifiSsid = wifiSsid;
         // network is considered not hidden by default
         mHiddenSSID = false;
     }
 
     /**
      * Returns the service set identifier (SSID) of the current 802.11 network.
-     * If the SSID is an ASCII string, it will be returned surrounded by double
-     * quotation marks.Otherwise, it is returned as a string of hex digits. The
+     * If the SSID can be decoded as UTF-8, it will be returned surrounded by double
+     * quotation marks. Otherwise, it is returned as a string of hex digits. The
      * SSID may be {@code null} if there is no network currently connected.
      * @return the SSID
      */
     public String getSSID() {
-        return mSSID;
+        if (mWifiSsid != null) {
+            String unicode = mWifiSsid.toString();
+            if (!TextUtils.isEmpty(unicode)) {
+                return "\"" + unicode + "\"";
+            } else {
+                return mWifiSsid.getHexString();
+            }
+        }
+        return WifiSsid.NONE;
+    }
+
+    /** @hide */
+    public WifiSsid getWifiSsid() {
+        return mWifiSsid;
     }
 
     void setBSSID(String BSSID) {
@@ -279,7 +294,7 @@
         StringBuffer sb = new StringBuffer();
         String none = "<none>";
 
-        sb.append("SSID: ").append(mSSID == null ? none : mSSID).
+        sb.append("SSID: ").append(mWifiSsid == null ? WifiSsid.NONE : mWifiSsid).
             append(", BSSID: ").append(mBSSID == null ? none : mBSSID).
             append(", MAC: ").append(mMacAddress == null ? none : mMacAddress).
             append(", Supplicant state: ").
@@ -308,7 +323,12 @@
         } else {
             dest.writeByte((byte)0);
         }
-        dest.writeString(getSSID());
+        if (mWifiSsid != null) {
+            dest.writeInt(1);
+            mWifiSsid.writeToParcel(dest, flags);
+        } else {
+            dest.writeInt(0);
+        }
         dest.writeString(mBSSID);
         dest.writeString(mMacAddress);
         dest.writeInt(mMeteredHint ? 1 : 0);
@@ -328,7 +348,9 @@
                         info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
                     } catch (UnknownHostException e) {}
                 }
-                info.setSSID(in.readString());
+                if (in.readInt() == 1) {
+                    info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in);
+                }
                 info.mBSSID = in.readString();
                 info.mMacAddress = in.readString();
                 info.mMeteredHint = in.readInt() != 0;
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 17c930b..ab54a15 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -645,9 +645,12 @@
          * id=network-id state=new-state
          */
         private void handleSupplicantStateChange(String dataString) {
-            String SSID = null;
+            WifiSsid wifiSsid = null;
             int index = dataString.lastIndexOf("SSID=");
-            if (index != -1) SSID = dataString.substring(index + 5);
+            if (index != -1) {
+                wifiSsid = WifiSsid.createFromAsciiEncoded(
+                        dataString.substring(index + 5));
+            }
             String[] dataTokens = dataString.split(" ");
 
             String BSSID = null;
@@ -690,7 +693,7 @@
             if (newSupplicantState == SupplicantState.INVALID) {
                 Log.w(TAG, "Invalid supplicant state: " + newState);
             }
-            notifySupplicantStateChange(networkId, SSID, BSSID, newSupplicantState);
+            notifySupplicantStateChange(networkId, wifiSsid, BSSID, newSupplicantState);
         }
     }
 
@@ -739,13 +742,14 @@
      * Send the state machine a notification that the state of the supplicant
      * has changed.
      * @param networkId the configured network on which the state change occurred
-     * @param SSID network name
+     * @param wifiSsid network name
      * @param BSSID network address
      * @param newState the new {@code SupplicantState}
      */
-    void notifySupplicantStateChange(int networkId, String SSID, String BSSID, SupplicantState newState) {
+    void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
+            SupplicantState newState) {
         mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
-                new StateChangeResult(networkId, SSID, BSSID, newState)));
+                new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
new file mode 100644
index 0000000..6f36111
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiSsid.java
@@ -0,0 +1,217 @@
+/*
+ * 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.net.wifi;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Stores SSID octets and handles conversion.
+ *
+ * For Ascii encoded string, any octet < 32 or > 127 is encoded as
+ * a "\x" followed by the hex representation of the octet.
+ * Exception chars are ", \, \e, \n, \r, \t which are escaped by a \
+ * See src/utils/common.c for the implementation in the supplicant.
+ *
+ * @hide
+ */
+public class WifiSsid implements Parcelable {
+    private static final String TAG = "WifiSsid";
+
+    public ByteArrayOutputStream octets = new ByteArrayOutputStream(32);
+
+    private static final int HEX_RADIX = 16;
+    public static final String NONE = "<unknown ssid>";
+
+    private WifiSsid() {
+    }
+
+    public static WifiSsid createFromAsciiEncoded(String asciiEncoded) {
+        WifiSsid a = new WifiSsid();
+        a.convertToBytes(asciiEncoded);
+        return a;
+    }
+
+    public static WifiSsid createFromHex(String hexStr) {
+        WifiSsid a = new WifiSsid();
+        int length = 0;
+        if (hexStr == null) return a;
+
+        if (hexStr.startsWith("0x") || hexStr.startsWith("0X")) {
+            hexStr = hexStr.substring(2);
+        }
+
+        for (int i = 0; i < hexStr.length()-1; i += 2) {
+            int val;
+            try {
+                val = Integer.parseInt(hexStr.substring(i, i + 2), HEX_RADIX);
+            } catch(NumberFormatException e) {
+                val = 0;
+            }
+            a.octets.write(val);
+        }
+        return a;
+    }
+
+    /* This function is equivalent to printf_decode() at src/utils/common.c in
+     * the supplicant */
+    private void convertToBytes(String asciiEncoded) {
+        int i = 0;
+        int val = 0;
+        while (i< asciiEncoded.length()) {
+            char c = asciiEncoded.charAt(i);
+            switch (c) {
+                case '\\':
+                    i++;
+                    switch(asciiEncoded.charAt(i)) {
+                        case '\\':
+                            octets.write('\\');
+                            break;
+                        case '"':
+                            octets.write('"');
+                            break;
+                        case 'n':
+                            octets.write('\n');
+                            break;
+                        case 'r':
+                            octets.write('\r');
+                            break;
+                        case 't':
+                            octets.write('\t');
+                            break;
+                        case 'e':
+                            octets.write(27); //escape char
+                            break;
+                        case 'x':
+                            i++;
+                            try {
+                                val = Integer.parseInt(asciiEncoded.substring(i, i + 2), HEX_RADIX);
+                            } catch (NumberFormatException e) {
+                                val = -1;
+                            }
+                            if (val < 0) {
+                                val = Character.digit(asciiEncoded.charAt(i), HEX_RADIX);
+                                if (val < 0) break;
+                                octets.write(val);
+                                i++;
+                            } else {
+                                octets.write(val);
+                                i += 2;
+                            }
+                            break;
+                        case '0':
+                        case '1':
+                        case '2':
+                        case '3':
+                        case '4':
+                        case '5':
+                        case '6':
+                        case '7':
+                            val = asciiEncoded.charAt(i) - '0';
+                            i++;
+                            if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
+                                val = val * 8 + asciiEncoded.charAt(i) - '0';
+                                i++;
+                            }
+                            if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
+                                val = val * 8 + asciiEncoded.charAt(i) - '0';
+                                i++;
+                            }
+                            octets.write(val);
+                            break;
+                        default:
+                            break;
+                    }
+                    break;
+                default:
+                    octets.write(c);
+                    i++;
+                    break;
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (octets.size() <= 0) return "";
+        // TODO: Handle conversion to other charsets upon failure
+        Charset charset = Charset.forName("UTF-8");
+        CharsetDecoder decoder = charset.newDecoder()
+                .onMalformedInput(CodingErrorAction.REPLACE)
+                .onUnmappableCharacter(CodingErrorAction.REPLACE);
+        CharBuffer out = CharBuffer.allocate(32);
+
+        CoderResult result = decoder.decode(ByteBuffer.wrap(octets.toByteArray()), out, true);
+        out.flip();
+        if (result.isError()) {
+            return NONE;
+        }
+        return out.toString();
+    }
+
+    /** @hide */
+    public byte[] getOctets() {
+        return  octets.toByteArray();
+    }
+
+    /** @hide */
+    public String getHexString() {
+        String out = "0x";
+        byte[] ssidbytes = getOctets();
+        for (int i = 0; i < octets.size(); i++) {
+            out += String.format("%02x", ssidbytes[i]);
+        }
+        return out;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(octets.size());
+        dest.writeByteArray(octets.toByteArray());
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public static final Creator<WifiSsid> CREATOR =
+        new Creator<WifiSsid>() {
+            public WifiSsid createFromParcel(Parcel in) {
+                WifiSsid ssid = new WifiSsid();
+                int length = in.readInt();
+                byte b[] = new byte[length];
+                in.readByteArray(b);
+                ssid.octets.write(b, 0, length);
+                return ssid;
+            }
+
+            public WifiSsid[] newArray(int size) {
+                return new WifiSsid[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 40111fa..4cbb824 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -138,10 +138,6 @@
     private boolean mScanResultIsPending = false;
     /* Tracks if the current scan settings are active */
     private boolean mSetScanActive = false;
-    /* High perf mode is true if an app has held a high perf Wifi Lock */
-    private boolean mHighPerfMode = false;
-    /* Tracks if user has disabled suspend optimizations through settings */
-    private AtomicBoolean mSuspendOptEnabled = new AtomicBoolean(true);
 
     private boolean mBluetoothConnectionActive = false;
 
@@ -338,10 +334,8 @@
     static final int CMD_START_PACKET_FILTERING           = BASE + 84;
     /* Clear packet filter */
     static final int CMD_STOP_PACKET_FILTERING            = BASE + 85;
-    /* Set suspend mode optimizations in the driver */
-    static final int CMD_SET_SUSPEND_OPTIMIZATIONS        = BASE + 86;
-    /* Clear suspend mode optimizations in the driver */
-    static final int CMD_CLEAR_SUSPEND_OPTIMIZATIONS      = BASE + 87;
+    /* Enable suspend mode optimizations in the driver */
+    static final int CMD_SET_SUSPEND_OPT_ENABLED          = BASE + 86;
     /* When there are no saved networks, we do a periodic scan to notify user of
      * an open network */
     static final int CMD_NO_NETWORKS_PERIODIC_SCAN        = BASE + 88;
@@ -386,8 +380,19 @@
      */
     private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
 
-    /* Tracks if power save is enabled in driver */
-    private boolean mPowerSaveEnabled = true;;
+    /* Tracks if suspend optimizations need to be disabled by DHCP,
+     * screen or due to high perf mode.
+     * When any of them needs to disable it, we keep the suspend optimizations
+     * disabled
+     */
+    private int mSuspendOptNeedsDisabled = 0;
+
+    private static final int SUSPEND_DUE_TO_DHCP       = 1;
+    private static final int SUSPEND_DUE_TO_HIGH_PERF  = 1<<1;
+    private static final int SUSPEND_DUE_TO_SCREEN     = 1<<2;
+
+    /* Tracks if user has enabled suspend optimizations through settings */
+    private AtomicBoolean mUserWantsSuspendOpt = new AtomicBoolean(true);
 
     /**
      * Default framework scan interval in milliseconds. This is used in the scenario in which
@@ -599,7 +604,7 @@
         mPrimaryDeviceType = mContext.getResources().getString(
                 com.android.internal.R.string.config_wifi_p2p_device_type);
 
-        mSuspendOptEnabled.set(Settings.Secure.getInt(mContext.getContentResolver(),
+        mUserWantsSuspendOpt.set(Settings.Secure.getInt(mContext.getContentResolver(),
                     Settings.Secure.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1);
 
         mContext.registerReceiver(
@@ -637,20 +642,20 @@
                         enableBackgroundScanCommand(false);
                     }
                     enableAllNetworks();
-                    if (mSuspendOptEnabled.get()) {
+                    if (mUserWantsSuspendOpt.get()) {
                         if (DBG) log("Clear suspend optimizations");
-                        sendMessage(CMD_CLEAR_SUSPEND_OPTIMIZATIONS);
+                        sendMessage(obtainMessage(CMD_SET_SUSPEND_OPT_ENABLED, 0, 0));
                     }
                 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                     enableRssiPolling(false);
                     if (mBackgroundScanSupported) {
                         enableBackgroundScanCommand(true);
                     }
-                    if (mSuspendOptEnabled.get()) {
+                    if (mUserWantsSuspendOpt.get()) {
                         if (DBG) log("Enable suspend optimizations");
                         //Allow 2s for suspend optimizations to be set
                         mSuspendWakeLock.acquire(2000);
-                        sendMessage(CMD_SET_SUSPEND_OPTIMIZATIONS);
+                        sendMessage(obtainMessage(CMD_SET_SUSPEND_OPT_ENABLED, 1, 0));
                     }
                 }
             }
@@ -671,7 +676,7 @@
                 new ContentObserver(getHandler()) {
                     @Override
                     public void onChange(boolean selfChange) {
-                        mSuspendOptEnabled.set(Settings.Secure.getInt(mContext.getContentResolver(),
+                        mUserWantsSuspendOpt.set(Settings.Secure.getInt(mContext.getContentResolver(),
                                 Settings.Secure.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1);
                     }
                 });
@@ -1172,8 +1177,8 @@
         sb.append("mLastNetworkId ").append(mLastNetworkId).append(LS);
         sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
         sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
-        sb.append("mHighPerfMode").append(mHighPerfMode).append(LS);
-        sb.append("mSuspendOptEnabled").append(mSuspendOptEnabled).append(LS);
+        sb.append("mUserWantsSuspendOpt ").append(mUserWantsSuspendOpt).append(LS);
+        sb.append("mSuspendOptNeedsDisabled ").append(mSuspendOptNeedsDisabled).append(LS);
         sb.append("Supplicant status").append(LS)
                 .append(mWifiNative.status()).append(LS).append(LS);
 
@@ -1191,8 +1196,7 @@
                 case CMD_START_DRIVER:
                 case CMD_SET_SCAN_MODE:
                 case CMD_SET_HIGH_PERF_MODE:
-                case CMD_SET_SUSPEND_OPTIMIZATIONS:
-                case CMD_CLEAR_SUSPEND_OPTIMIZATIONS:
+                case CMD_SET_SUSPEND_OPT_ENABLED:
                 case CMD_ENABLE_BACKGROUND_SCAN:
                 case CMD_ENABLE_ALL_NETWORKS:
                 return false;
@@ -1324,6 +1328,32 @@
         setFrequencyBand(band, false);
     }
 
+    private void setSuspendOptimizationsNative(int reason, boolean enabled) {
+        if (DBG) log("setSuspendOptimizationsNative: " + reason + " " + enabled);
+        if (enabled) {
+            mSuspendOptNeedsDisabled &= ~reason;
+            /* None of dhcp, screen or highperf need it disabled and user wants it enabled */
+            if (mSuspendOptNeedsDisabled == 0 && mUserWantsSuspendOpt.get()) {
+                mWifiNative.setSuspendOptimizations(true);
+                if (DBG) log("Enabled, mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
+            }
+        } else {
+            mSuspendOptNeedsDisabled |= reason;
+            mWifiNative.setSuspendOptimizations(false);
+            if (DBG) log("Disabled, mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
+        }
+    }
+
+    private void setSuspendOptimizations(int reason, boolean enabled) {
+        if (DBG) log("setSuspendOptimizations: " + reason + " " + enabled);
+        if (enabled) {
+            mSuspendOptNeedsDisabled &= ~reason;
+        } else {
+            mSuspendOptNeedsDisabled |= reason;
+        }
+        if (DBG) log("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
+    }
+
     private void setWifiState(int wifiState) {
         final int previousWifiState = mWifiState.get();
 
@@ -1403,7 +1433,7 @@
         int freq = 0;
         long tsf = 0;
         String flags = "";
-        String ssid = "";
+        WifiSsid wifiSsid = null;
 
         if (scanResults == null) {
             return;
@@ -1441,22 +1471,26 @@
                 } else if (line.startsWith(FLAGS_STR)) {
                     flags = line.substring(FLAGS_STR.length());
                 } else if (line.startsWith(SSID_STR)) {
-                    ssid = line.substring(SSID_STR.length());
-                    if (ssid == null) ssid = "";
+                    wifiSsid = WifiSsid.createFromAsciiEncoded(
+                            line.substring(SSID_STR.length()));
                 } else if (line.startsWith(DELIMITER_STR)) {
                     if (bssid != null) {
+                        String ssid = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
                         String key = bssid + ssid;
                         ScanResult scanResult = mScanResultCache.get(key);
                         if (scanResult != null) {
                             scanResult.level = level;
-                            scanResult.SSID = ssid;
+                            scanResult.wifiSsid = wifiSsid;
+                            // Keep existing API
+                            scanResult.SSID = (wifiSsid != null) ? wifiSsid.toString() :
+                                    WifiSsid.NONE;
                             scanResult.capabilities = flags;
                             scanResult.frequency = freq;
                             scanResult.timestamp = tsf;
                         } else {
                             scanResult =
                                 new ScanResult(
-                                        ssid, bssid, flags, level, freq, tsf);
+                                        wifiSsid, bssid, flags, level, freq, tsf);
                             mScanResultCache.put(key, scanResult);
                         }
                         mScanResults.add(scanResult);
@@ -1466,7 +1500,7 @@
                     freq = 0;
                     tsf = 0;
                     flags = "";
-                    ssid = "";
+                    wifiSsid = null;
                 }
             }
         }
@@ -1652,7 +1686,7 @@
         }
 
         mWifiInfo.setBSSID(stateChangeResult.BSSID);
-        mWifiInfo.setSSID(stateChangeResult.SSID);
+        mWifiInfo.setSSID(stateChangeResult.wifiSsid);
 
         mSupplicantStateTracker.sendMessage(Message.obtain(message));
 
@@ -1732,18 +1766,16 @@
                     mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
         }
 
-        /* Disable power save during DHCP */
-        if (mPowerSaveEnabled) {
-            mPowerSaveEnabled = false;
-            mWifiNative.setPowerSave(mPowerSaveEnabled);
-        }
+        /* Disable power save and suspend optimizations during DHCP */
+        mWifiNative.setPowerSave(false);
+        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false);
     }
 
 
     void handlePostDhcpSetup() {
-        /* Restore power save */
-        mPowerSaveEnabled = true;
-        mWifiNative.setPowerSave(mPowerSaveEnabled);
+        /* Restore power save and suspend optimizations */
+        mWifiNative.setPowerSave(true);
+        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true);
 
         // Set the coexistence mode back to its default value
         mWifiNative.setBluetoothCoexistenceMode(
@@ -1876,7 +1908,11 @@
                     mEnableBackgroundScan = (message.arg1 == 1);
                     break;
                 case CMD_SET_HIGH_PERF_MODE:
-                    mHighPerfMode = (message.arg1 == 1);
+                    if (message.arg1 == 1) {
+                        setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, false);
+                    } else {
+                        setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, true);
+                    }
                     break;
                     /* Discard */
                 case CMD_LOAD_DRIVER:
@@ -1923,14 +1959,18 @@
                 case CMD_RESPONSE_AP_CONFIG:
                 case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
                 case WifiWatchdogStateMachine.GOOD_LINK_DETECTED:
-                case CMD_CLEAR_SUSPEND_OPTIMIZATIONS:
                 case CMD_NO_NETWORKS_PERIODIC_SCAN:
                     break;
                 case DhcpStateMachine.CMD_ON_QUIT:
                     mDhcpStateMachine = null;
                     break;
-                case CMD_SET_SUSPEND_OPTIMIZATIONS:
-                    mSuspendWakeLock.release();
+                case CMD_SET_SUSPEND_OPT_ENABLED:
+                    if (message.arg1 == 1) {
+                        mSuspendWakeLock.release();
+                        setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, true);
+                    } else {
+                        setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, false);
+                    }
                     break;
                 case WifiMonitor.DRIVER_HUNG_EVENT:
                     setWifiEnabled(false);
@@ -2666,7 +2706,7 @@
                 mWifiNative.stopFilteringMulticastV4Packets();
             }
 
-            mWifiNative.setPowerSave(mPowerSaveEnabled);
+            mWifiNative.setPowerSave(true);
 
             if (mIsScanMode) {
                 mWifiNative.setScanResultHandling(SCAN_ONLY_MODE);
@@ -2793,20 +2833,19 @@
                         loge("Illegal arugments to CMD_STOP_PACKET_FILTERING");
                     }
                     break;
-                case CMD_SET_SUSPEND_OPTIMIZATIONS:
-                    if (!mHighPerfMode) {
-                        mWifiNative.setSuspendOptimizations(true);
+                case CMD_SET_SUSPEND_OPT_ENABLED:
+                    if (message.arg1 == 1) {
+                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, true);
+                        mSuspendWakeLock.release();
+                    } else {
+                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, false);
                     }
-                    mSuspendWakeLock.release();
-                    break;
-                case CMD_CLEAR_SUSPEND_OPTIMIZATIONS:
-                    mWifiNative.setSuspendOptimizations(false);
                     break;
                 case CMD_SET_HIGH_PERF_MODE:
-                    mHighPerfMode = (message.arg1 == 1);
-                    if (mHighPerfMode) {
-                        //Disable any suspend optimizations
-                        mWifiNative.setSuspendOptimizations(false);
+                    if (message.arg1 == 1) {
+                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, false);
+                    } else {
+                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
                     }
                     break;
                 default: