Merge "Add API for scrolling AbsListView by a pixel amount"
diff --git a/Android.mk b/Android.mk
index 8f62777..4b1fa58 100644
--- a/Android.mk
+++ b/Android.mk
@@ -197,6 +197,7 @@
 	core/java/com/android/internal/app/IAppOpsCallback.aidl \
 	core/java/com/android/internal/app/IAppOpsService.aidl \
 	core/java/com/android/internal/app/IBatteryStats.aidl \
+	core/java/com/android/internal/app/IProcessStats.aidl \
 	core/java/com/android/internal/app/IUsageStats.aidl \
 	core/java/com/android/internal/app/IMediaContainerService.aidl \
 	core/java/com/android/internal/appwidget/IAppWidgetService.aidl \
diff --git a/api/current.txt b/api/current.txt
index 9a80383..71ab2d5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12059,6 +12059,9 @@
   public static final class MediaCodec.CryptoException extends java.lang.RuntimeException {
     ctor public MediaCodec.CryptoException(int, java.lang.String);
     method public int getErrorCode();
+    field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
+    field public static final int ERROR_NO_KEY = 1; // 0x1
+    field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
   }
 
   public static final class MediaCodec.CryptoInfo {
@@ -12810,6 +12813,10 @@
     method public abstract void onPlaybackPositionUpdate(long);
   }
 
+  public final class ResourceBusyException extends android.media.MediaDrmException {
+    ctor public ResourceBusyException(java.lang.String);
+  }
+
   public class Ringtone {
     method public int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java
index 21995c0..19d74ed 100644
--- a/core/java/android/net/CaptivePortalTracker.java
+++ b/core/java/android/net/CaptivePortalTracker.java
@@ -28,11 +28,23 @@
 import android.database.ContentObserver;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.os.UserHandle;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.provider.Settings;
+import android.telephony.CellIdentityCdma;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityWcdma;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
 import android.telephony.TelephonyManager;
 
 import com.android.internal.util.State;
@@ -44,6 +56,7 @@
 import java.net.Inet4Address;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.util.List;
 
 import com.android.internal.R;
 
@@ -60,12 +73,29 @@
 
     private static final int SOCKET_TIMEOUT_MS = 10000;
 
+    public static final String ACTION_NETWORK_CONDITIONS_MEASURED =
+            "android.net.conn.NETWORK_CONDITIONS_MEASURED";
+    public static final String EXTRA_CONNECTIVITY_TYPE = "extra_connectivity_type";
+    public static final String EXTRA_NETWORK_TYPE = "extra_network_type";
+    public static final String EXTRA_RESPONSE_RECEIVED = "extra_response_received";
+    public static final String EXTRA_IS_CAPTIVE_PORTAL = "extra_is_captive_portal";
+    public static final String EXTRA_CELL_ID = "extra_cellid";
+    public static final String EXTRA_SSID = "extra_ssid";
+    public static final String EXTRA_BSSID = "extra_bssid";
+    /** real time since boot */
+    public static final String EXTRA_REQUEST_TIMESTAMP_MS = "extra_request_timestamp_ms";
+    public static final String EXTRA_RESPONSE_TIMESTAMP_MS = "extra_response_timestamp_ms";
+
+    private static final String PERMISSION_ACCESS_NETWORK_CONDITIONS =
+            "android.permission.ACCESS_NETWORK_CONDITIONS";
+
     private String mServer;
     private String mUrl;
     private boolean mNotificationShown = false;
     private boolean mIsCaptivePortalCheckEnabled = false;
     private IConnectivityManager mConnService;
     private TelephonyManager mTelephonyManager;
+    private WifiManager mWifiManager;
     private Context mContext;
     private NetworkInfo mNetworkInfo;
 
@@ -92,6 +122,7 @@
         mContext = context;
         mConnService = cs;
         mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
         mProvisioningObserver = new ProvisioningObserver();
 
         IntentFilter filter = new IntentFilter();
@@ -319,7 +350,8 @@
     }
 
     /**
-     * Do a URL fetch on a known server to see if we get the data we expect
+     * Do a URL fetch on a known server to see if we get the data we expect.
+     * Measure the response time and broadcast that.
      */
     private boolean isCaptivePortal(InetAddress server) {
         HttpURLConnection urlConnection = null;
@@ -327,6 +359,7 @@
 
         mUrl = "http://" + server.getHostAddress() + "/generate_204";
         if (DBG) log("Checking " + mUrl);
+        long requestTimestamp = -1;
         try {
             URL url = new URL(mUrl);
             urlConnection = (HttpURLConnection) url.openConnection();
@@ -334,11 +367,26 @@
             urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
             urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
             urlConnection.setUseCaches(false);
+
+            // Time how long it takes to get a response to our request
+            requestTimestamp = SystemClock.elapsedRealtime();
+
             urlConnection.getInputStream();
+
+            // Time how long it takes to get a response to our request
+            long responseTimestamp = SystemClock.elapsedRealtime();
+
             // we got a valid response, but not from the real google
-            return urlConnection.getResponseCode() != 204;
+            boolean isCaptivePortal = urlConnection.getResponseCode() != 204;
+
+            sendNetworkConditionsBroadcast(true /* response received */, isCaptivePortal,
+                    requestTimestamp, responseTimestamp);
+            return isCaptivePortal;
         } catch (IOException e) {
             if (DBG) log("Probably not a portal: exception " + e);
+            if (requestTimestamp != -1) {
+                sendFailedCaptivePortalCheckBroadcast(requestTimestamp);
+            } // else something went wrong with setting up the urlConnection
             return false;
         } finally {
             if (urlConnection != null) {
@@ -352,12 +400,15 @@
         try {
             inetAddress = InetAddress.getAllByName(hostname);
         } catch (UnknownHostException e) {
+            sendFailedCaptivePortalCheckBroadcast(SystemClock.elapsedRealtime());
             return null;
         }
 
         for (InetAddress a : inetAddress) {
             if (a instanceof Inet4Address) return a;
         }
+
+        sendFailedCaptivePortalCheckBroadcast(SystemClock.elapsedRealtime());
         return null;
     }
 
@@ -414,4 +465,80 @@
         }
         mNotificationShown = visible;
     }
+
+    private void sendFailedCaptivePortalCheckBroadcast(long requestTimestampMs) {
+        sendNetworkConditionsBroadcast(false /* response received */, false /* ignored */,
+                requestTimestampMs, 0 /* ignored */);
+    }
+
+    /**
+     * @param responseReceived - whether or not we received a valid HTTP response to our request.
+     * If false, isCaptivePortal and responseTimestampMs are ignored
+     */
+    private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal,
+            long requestTimestampMs, long responseTimestampMs) {
+        if (Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0) {
+            if (DBG) log("Don't send network conditions - lacking user consent.");
+            return;
+        }
+
+        Intent latencyBroadcast = new Intent(ACTION_NETWORK_CONDITIONS_MEASURED);
+        switch (mNetworkInfo.getType()) {
+            case ConnectivityManager.TYPE_WIFI:
+                WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
+                if (currentWifiInfo != null) {
+                    latencyBroadcast.putExtra(EXTRA_SSID, currentWifiInfo.getSSID());
+                    latencyBroadcast.putExtra(EXTRA_BSSID, currentWifiInfo.getBSSID());
+                } else {
+                    if (DBG) logw("network info is TYPE_WIFI but no ConnectionInfo found");
+                    return;
+                }
+                break;
+            case ConnectivityManager.TYPE_MOBILE:
+                latencyBroadcast.putExtra(EXTRA_NETWORK_TYPE, mTelephonyManager.getNetworkType());
+                List<CellInfo> info = mTelephonyManager.getAllCellInfo();
+                if (info == null) return;
+                StringBuffer uniqueCellId = new StringBuffer();
+                int numRegisteredCellInfo = 0;
+                for (CellInfo cellInfo : info) {
+                    if (cellInfo.isRegistered()) {
+                        numRegisteredCellInfo++;
+                        if (numRegisteredCellInfo > 1) {
+                            if (DBG) log("more than one registered CellInfo.  Can't " +
+                                    "tell which is active.  Bailing.");
+                            return;
+                        }
+                        if (cellInfo instanceof CellInfoCdma) {
+                            CellIdentityCdma cellId = ((CellInfoCdma) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else if (cellInfo instanceof CellInfoGsm) {
+                            CellIdentityGsm cellId = ((CellInfoGsm) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else if (cellInfo instanceof CellInfoLte) {
+                            CellIdentityLte cellId = ((CellInfoLte) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else if (cellInfo instanceof CellInfoWcdma) {
+                            CellIdentityWcdma cellId = ((CellInfoWcdma) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else {
+                            if (DBG) logw("Registered cellinfo is unrecognized");
+                            return;
+                        }
+                    }
+                }
+                break;
+            default:
+                return;
+        }
+        latencyBroadcast.putExtra(EXTRA_CONNECTIVITY_TYPE, mNetworkInfo.getType());
+        latencyBroadcast.putExtra(EXTRA_RESPONSE_RECEIVED, responseReceived);
+        latencyBroadcast.putExtra(EXTRA_REQUEST_TIMESTAMP_MS, requestTimestampMs);
+
+        if (responseReceived) {
+            latencyBroadcast.putExtra(EXTRA_IS_CAPTIVE_PORTAL, isCaptivePortal);
+            latencyBroadcast.putExtra(EXTRA_RESPONSE_TIMESTAMP_MS, responseTimestampMs);
+        }
+        mContext.sendBroadcast(latencyBroadcast, PERMISSION_ACCESS_NETWORK_CONDITIONS);
+    }
 }
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index 2d67264..5df5214 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -30,6 +30,8 @@
     public boolean batteryPresent;
     public int batteryLevel;
     public int batteryVoltage;
+    public int batteryCurrentNow;
+    public int batteryChargeCounter;
     public int batteryTemperature;
     public String batteryTechnology;
 
@@ -47,6 +49,8 @@
         batteryPresent = p.readInt() == 1 ? true : false;
         batteryLevel = p.readInt();
         batteryVoltage = p.readInt();
+        batteryCurrentNow = p.readInt();
+        batteryChargeCounter = p.readInt();
         batteryTemperature = p.readInt();
         batteryTechnology = p.readString();
     }
@@ -60,6 +64,8 @@
         p.writeInt(batteryPresent ? 1 : 0);
         p.writeInt(batteryLevel);
         p.writeInt(batteryVoltage);
+        p.writeInt(batteryCurrentNow);
+        p.writeInt(batteryChargeCounter);
         p.writeInt(batteryTemperature);
         p.writeString(batteryTechnology);
     }
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 160ec8a..0f765fa 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -1112,6 +1112,7 @@
             try {
                 mFragmentBreadCrumbs = (FragmentBreadCrumbs)crumbs;
             } catch (ClassCastException e) {
+                setTitle(title);
                 return;
             }
             if (mFragmentBreadCrumbs == null) {
@@ -1125,12 +1126,17 @@
                 // Hide the breadcrumb section completely for single-pane
                 View bcSection = findViewById(com.android.internal.R.id.breadcrumb_section);
                 if (bcSection != null) bcSection.setVisibility(View.GONE);
+                setTitle(title);
             }
             mFragmentBreadCrumbs.setMaxVisible(2);
             mFragmentBreadCrumbs.setActivity(this);
         }
-        mFragmentBreadCrumbs.setTitle(title, shortTitle);
-        mFragmentBreadCrumbs.setParentTitle(null, null, null);
+        if (mFragmentBreadCrumbs.getVisibility() != View.VISIBLE) {
+            setTitle(title);
+        } else {
+            mFragmentBreadCrumbs.setTitle(title, shortTitle);
+            mFragmentBreadCrumbs.setParentTitle(null, null, null);
+        }
     }
 
     /**
diff --git a/core/java/com/android/internal/app/IProcessStats.aidl b/core/java/com/android/internal/app/IProcessStats.aidl
new file mode 100644
index 0000000..e4c8bd2
--- /dev/null
+++ b/core/java/com/android/internal/app/IProcessStats.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.ComponentName;
+import android.os.ParcelFileDescriptor;
+import com.android.internal.app.ProcessStats;
+
+interface IProcessStats {
+    byte[] getCurrentStats(out List<ParcelFileDescriptor> historic);
+}
diff --git a/core/java/com/android/internal/app/ProcessStats.aidl b/core/java/com/android/internal/app/ProcessStats.aidl
new file mode 100644
index 0000000..48b1f85
--- /dev/null
+++ b/core/java/com/android/internal/app/ProcessStats.aidl
@@ -0,0 +1,19 @@
+/*
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.internal.app;
+
+parcelable ProcessStats;
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 86b34f5c..0cd6f4a 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -234,7 +234,7 @@
         recorderCallback,// callback_t
         lpCallbackData,// void* user
         0,             // notificationFrames,
-        true,          // threadCanCallJava)
+        true,          // threadCanCallJava
         sessionId);
 
     if (lpRecorder->initCheck() != NO_ERROR) {
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 8dc2fc6..0f429005 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -100,7 +100,7 @@
         jobject surface) {
 
     sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, surface));
-    sp<ANativeWindow> window = new Surface(producer);
+    sp<ANativeWindow> window = new Surface(producer, true);
 
     window->incStrong((void*)android_view_TextureView_createNativeWindow);
     SET_INT(textureView, gTextureViewClassInfo.nativeWindow, jint(window.get()));
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a9a14ad..d106cf2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -201,6 +201,7 @@
     <protected-broadcast android:name="android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED" />
     <protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" />
+    <protected-broadcast android:name="android.net.conn.NETWORK_CONDITIONS_MEASURED" />
     <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE" />
     <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE" />
     <protected-broadcast android:name="android.intent.action.AIRPLANE_MODE" />
@@ -2399,6 +2400,13 @@
         android:description="@string/permdesc_invokeCarrierSetup"
         android:protectionLevel="signature|system" />
 
+    <!-- Allows an application to listen for network condition observations.
+         @hide This is not a third-party API (intended for system apps). -->
+    <permission android:name="android.permission.ACCESS_NETWORK_CONDITIONS"
+        android:label="@string/permlab_accessNetworkConditions"
+        android:description="@string/permdesc_accessNetworkConditions"
+        android:protectionLevel="signature|system" />
+
     <!-- The system process is explicitly the only one allowed to launch the
          confirmation UI for full backup/restore -->
     <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 5812053..02cd8cd 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -30,24 +30,19 @@
         android:layout_weight="1">
 
         <LinearLayout
+            style="?attr/preferenceHeaderPanelStyle"
             android:id="@+id/headers"
             android:orientation="vertical"
             android:layout_width="0px"
             android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/preference_screen_side_margin_negative"
-            android:layout_marginStart="@dimen/preference_screen_side_margin"
             android:layout_weight="@integer/preferences_left_pane_weight">
 
             <ListView android:id="@android:id/list"
+                style="?attr/preferenceListStyle"
                 android:layout_width="match_parent"
                 android:layout_height="0px"
                 android:layout_weight="1"
-                android:paddingStart="@dimen/preference_screen_header_padding_side"
-                android:paddingEnd="@dimen/preference_screen_header_padding_side"
-                android:paddingTop="@dimen/preference_screen_header_vertical_padding"
-                android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
                 android:clipToPadding="false"
-                android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
                 android:drawSelectorOnTop="false"
                 android:cacheColorHint="@android:color/transparent"
                 android:listPreferredItemHeight="48dp"
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index abfb1f2..4e895b0 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -25,13 +25,12 @@
     android:layout_removeBorders="true">
 
     <ListView android:id="@android:id/list"
+        style="?attr/preferenceFragmentListStyle"
         android:layout_width="match_parent"
         android:layout_height="0px"
         android:layout_weight="1"
         android:paddingTop="0dip"
         android:paddingBottom="@dimen/preference_fragment_padding_bottom"
-        android:paddingStart="@dimen/preference_fragment_padding_side"
-        android:paddingEnd="@dimen/preference_fragment_padding_side"
         android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
         android:clipToPadding="false"
         android:drawSelectorOnTop="false"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 980ae05..06d6895 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -362,10 +362,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Laat die houer toe om aan die top-koppelvlak van \'n drukdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"kry toegang tot alle druktake"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Gee die houer toegang tot druktake wat deur \'n ander program geskep is. Behoort nooit vir normale programme nodig te wees nie."</string>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"bind aan NFC-diens"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Laat die houer toe om die programme wat NFC-kaarte nastrewe, te bind. Behoort nooit vir normale programme nodig te wees nie."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind aan \'n teksdiens"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n teksdiens (bv SpellCheckerService) te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind aan \'n VPN-diens"</string>
@@ -474,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Laat die program toe om InputFlinger se laevlak-kenmerke te gebruik."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"stel Wi-Fi-skerms op"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Laat die program toe om Wi-Fi-skerms op te stel en daaraan te koppel."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"beheer Wi-Fi-skerms"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Laat die program toe om laevlak-kenmerke van Wi-Fi-skerms te beheer."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 0683c06..d554d54 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"መተግበሪያው ባለአነስተኛ የInputFlinger ባህሪያት እንዲጠቀም ይፈቅድለታል።"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"የWifi ማሳያዎችን አዋቅር"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"መተግበሪያው የWifi ማሳያዎችን እንዲያዋቅርና ከእነሱ ጋር እንዲገናኝ ይፈቅድለታል።"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"የWifi ማሳያዎችን ተቆጣጠር"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"መተግበሪያው በዝቅተኛ ደረጃ ላይ ያሉ የWifi ማሳያዎችን እንዲቆጣጠር ይፈቅድለታል።"</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 79d15f7..60dc57e 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"للسماح للتطبيق باستخدام ميزات InputFlinger ذات المستوى المنخفض."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"تهيئة شاشات Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"للسماح للتطبيق بتهيئة شاشات Wi-Fi والاتصال بها."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"التحكم في شاشات Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"للسماح للتطبيق بالتحكم في الميزات ذات المستوى المنخفض في شاشات Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 99dfcbf..86bb766 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -484,6 +484,8 @@
     <skip />
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"налада дысплеяў Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дазволiць прыкладанню наладжвацца i падключацца да дысплеяў Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"кіраванне дысплеямi Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Прыкладанне зможа кіраваць нізкім узроўнем функцый дысплеяў Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index c4f08b5..1452ecf 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -362,10 +362,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"достъп до всички задания за отпечатване"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Разрешава на притежателя да осъществява достъп до създадените от друго приложение задания за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"обвързване с услуга за КБП"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Разрешава на притежателя да се обвързва с приложения, които емулират карти за КБП. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"обвързване с текстова услуга"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на текстова услуга (напр. SpellCheckerService). Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"обвързване с услуга за VPN"</string>
@@ -474,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Разрешава на приложението да използва функциите на InputFlinger от ниско ниво."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"конфигуриране на дисплеите през WiFi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Разрешава на приложението да конфигурира и да се свързва с дисплеите през WiFi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контролиране на дисплеите през WiFi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Разрешава на приложението да контролира функциите от ниско ниво на дисплеите през WiFi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index f0878d9..96a35d0 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permet que l\'aplicació utilitzi funcions InputFlinger de baix nivell."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configuració de les pantalles Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet a l\'aplicació configurar-se i connectar-se a les pantalles Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control de les pantalles Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet a l\'aplicació controlar les funcions de baix nivell de les pantalles Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 86420cd..e9d65f80 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -474,6 +474,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Umožňuje aplikaci používat nízkoúrovňové funkce InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurovat displeje přes Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Povoluje aplikaci připojit a konfigurovat displeje přes Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládat displeje přes Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Povoluje aplikaci ovládat základní funkce displejů přes Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
@@ -1479,8 +1481,7 @@
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Obrazovka HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Překryvná vrstva č. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", zabezpečené"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Bezdrátový displej je připojen"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Tato obrazovka se zobrazuje v jiném zařízení"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Odpojit"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 8566763..c97c7e7 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Giver appen tilladelse til at bruge SurfaceFlinger-funktioner på lavt niveau."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurer Wi-Fi-skærme"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillader, at appen konfigurerer og opretter forbindelse til Wi-Fi-skærme."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollér Wi-Fi-skærme"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tillader, at appen kontrollerer Wi-Fi-skærmfunktioner på lavt niveau."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 85f252a..b26f65b 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -362,10 +362,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ermöglicht dem Inhaber, sich an die Oberfläche eines Druckdienstes auf oberster Ebene zu binden. Sollte für normale Apps nie benötigt werden."</string>
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"Auf alle Druckaufträge zugreifen"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Ermöglicht dem Inhaber den Zugriff auf von einer anderen App erstellte Druckaufträge. Sollte für normale Apps nie benötigt werden."</string>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"An NFC-Dienst binden"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ermöglicht dem Inhaber die Bindung an Apps, die NFC-Karten emulieren. Dies sollte für normale Apps niemals notwendig sein."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"An einen Textdienst binden"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Ermöglicht dem Halter, sich an die Oberfläche eines Textdienstes auf oberster Ebene zu binden, z. B. eines Rechtschreibprüfungsdienstes. Sollte nie für normale Apps benötigt werden."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"An einen VPN-Dienst binden"</string>
@@ -474,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Ermöglicht der App, die systemnahen InputFlinger-Funktionen zu verwenden"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"WLAN-Anzeigen konfigurieren"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Erlaubt der App, WLAN-Anzeigen zu konfigurieren und eine Verbindung zu diesen herzustellen"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WLAN-Anzeigen steuern"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Erlaubt der App, untergeordnete Funktionen von WLAN-Anzeigen zu steuern"</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b0c338b..571f155 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Επιτρέπει σε μια εφαρμογή να χρησιμοποιεί λειτουργίες InputFlinger χαμηλού επιπέδου."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"διαμόρφωση οθονών Wifi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Επιτρέπει τη διαμόρφωση της εφαρμογής και τη σύνδεσης σε οθόνες Wifi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"έλεγχος οθονών Wifi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Επιτρέπει στην εφαρμογή τον έλεγχο των λειτουργιών χαμηλού επιπέδου των οθονών Wifi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 68ef4b1..3a08f98 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Allows the app to use InputFlinger low-level features."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configure Wi-Fi displays"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Allows the app to configure and connect to Wi-Fi displays."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control Wi-Fi displays"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Allows the app to control low-level features of Wi-Fi displays."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 16c16bd..959729b 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -362,10 +362,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de impresión. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acceder a todos los trabajos de impresión"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite al propietario acceder a trabajos de impresión creados con otra aplicación. Las aplicaciones normales no deberían necesitar este permiso."</string>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"Vincular con servicio NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite vincular con aplicaciones que emulen tarjetas NFC. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a un servicio de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite al titular vincularse a la interfaz de nivel superior de un servicio de texto (p. ej., SpellCheckerService). Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"vincular con un servicio de VPN"</string>
@@ -474,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que la aplicación utilice funciones de InputFlinger de bajo nivel."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar pantallas Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que la aplicación configure y se conecte a pantallas Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar pantallas Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que la aplicación controle funciones de bajo nivel de las pantallas Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
@@ -1479,8 +1479,7 @@
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Pantalla HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposición #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segura"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Se conectó la pantalla inalámbrica"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Esta pantalla se muestra en otro dispositivo."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconectar"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index f64c0a0..c12cb76 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que la aplicación utilice funciones de bajo nivel de SurfaceFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar pantallas Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que la aplicación configure pantallas Wi-Fi y se conecte a ellas."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar pantallas Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que la aplicación controle funciones de bajo nivel de pantallas Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 71832c8..82243c1 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -363,7 +363,7 @@
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"juurdepääs kõikidele printimistöödele"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Lubab omanikule juurdepääsu teise rakenduse loodud printimistöödele. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC-teenusega sidumine"</string>
-    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Lubab kasutajal luua seosed rakendustega, mis jäljendavad NFC-kaarte. Pole kunagi vajalik tavaliste rakenduste korral."</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Lubab õiguste omajal luua seosed rakendustega, mis emuleerivad NFC-kaarte. Pole kunagi vajalik tavaliste rakenduste korral."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tekstiteenusega sidumine"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Võimaldab omanikul siduda tekstiteenuse (nt SpellCheckerService) ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"seo VPN-teenusega"</string>
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Lubab rakendusel kasutada InputFlingeri madalatasemelisi funktsioone."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"WiFi-ekraanide seadistamine"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Lubab rakendusel seadistada WiFi-ekraane ja nendega ühendus luua."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WiFi-ekraanide juhtimine"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Lubab rakendusel juhtida WiFi-ekraanide madala taseme funktsioone."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 9c863cf..3216d99 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -362,10 +362,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"به برنامه اجازه می‌دهد که به رابط سطح بالای سرویس چاپ متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"دسترسی به تمام کارهای چاپ"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"به دارنده اجازه دسترسی به کارهای چاپی ایجاد شده توسط برنامه‌ای دیگر را می‌دهد.هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"اتصال به سرویس NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"به دارنده اجازه می‌دهد به برنامه‌هایی متصل شود که مشابه با کارت‌های NFC عمل می‌کنند. هرگز نباید برای برنامه‌های عادی مورد نیاز باشد."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"اتصال به یک سرویس متنی"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"به دارنده اجازه می‌دهد خود را به یک رابط سطح بالای خدمات متنی مرتبط کند (برای مثال SpellCheckerService). هرگز برای برنامه‌های عادی لازم نیست."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"اتصال به یک سرویس VPN"</string>
@@ -474,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"اجازه می‎دهد برنامه از قابلیت‌های سطح پایین InputFlinger استفاده کند."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"پیکربندی صفحه نمایش‌های Wi‑Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"به برنامه اجازه می‌دهد تا اتصال به صفحات نمایش Wi‑Fi را پیکربندی کند."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"کنترل صفحه نمایش‌های Wi‑Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"به برنامه اجازه می‌دهد که ویژگی‌های سطح پایین صفحه‌های نمایش Wi‑Fi را کنترل کند."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
@@ -1479,8 +1479,7 @@
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"صفحه HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"همپوشانی #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"، امن"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"نمایشگر بی‌سیم متصل است"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"این صفحه در حال نمایش در دستگاه دیگری است"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"قطع اتصال"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index d431fcc..86a793f 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Antaa sovelluksen käyttää InputFlingerin matalan tason ominaisuuksia."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"määritä wifi-näyttöjen asetukset"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Antaa sovelluksen määrittää wifi-näyttöjä ja muodostaa yhteyden niihin."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"hallitse wifi-näyttöjä"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Antaa sovelluksen hallita wifi-näyttöjen matalan tason ominaisuuksia."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 7409912..f71be94 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -474,6 +474,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permet à l\'application d\'utiliser les fonctionnalités de base d\'InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurer les écrans Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet à l\'application de configurer des écrans Wi-Fi et de s\'y connecter."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"contrôler les écrans Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet à l\'application de contrôler les fonctionnalités de base des écrans Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 9f95156..31f4cb6 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"एप्‍लिकेशन को InputFlinger निम्‍न-स्‍तर सुविधाओं का उपयोग करने देता है."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi डिस्प्ले को कॉन्फ़िगर करें"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"एप्लिकेशन को कॉन्फ़िगर करने देता है और Wifi डिस्प्ले से कनेक्ट करता है."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi डिस्प्ले को नियंत्रित करें"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"एप्लिकेशन को Wifi डिस्प्ले की निम्न-स्तर की सुविधाएं नियंत्रित करने देता है."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index ca467ec..88e6a91 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Dopušta aplikaciji upotrebu značajki niske razine InputFlingera."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfiguriraj Wifi zaslone"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Omogućuje aplikaciji konfiguriranje i povezivanje s Wi-Fi zaslonima."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"upravljaj Wifi zaslonima"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Omogućuje aplikaciji upravljanje značajkama Wi-Fi zaslona niske razine."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index ac90a93..ee458b8 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Lehetővé teszi az alkalmazás számára az InputFlinger alacsony szintű funkciók használatát."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fi kijelzők konfigurálása"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Lehetővé teszi, hogy az alkalmazás Wi-Fi kijelzőket konfiguráljon, és csatlakozzon hozzájuk."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi kijelzők irányítása"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Lehetővé teszi, hogy az alkalmazás irányítsa a Wi-Fi kijelzők alacsonyabb szintű funkcióit."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index c197e3b..bc8517c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -474,6 +474,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Memungkinkan aplikasi menggunakan fitur tingkat rendah InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"mengonfigurasi tampilan Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Izinkan aplikasi mengonfigurasi dan terhubung ke tampilan Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"mengontrol tampilan Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Izinkan aplikasi mengontrol fitur tingkat rendah dari tampilan Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 7846956..60f40ae 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Consente all\'applicazione di utilizzare funzioni di basso livello InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurazione di schermi Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Consente all\'applicazione di configurare schermi Wi-Fi e di collegarsi a essi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controllo di schermi Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Consente all\'applicazione di controllare le funzioni di basso livello di schermi Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index c50cc14..2c84060 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"מאפשרת לאפליקציה להשתמש בתכונות ברמה נמוכה של InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"הגדר תצוגות Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"מאפשר לאפליקציה להגדיר ולהתחבר לתצוגות Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"שלוט בתצוגות Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"מאפשר לאפליקציה לשלוט בתכונות ברמה נמוכה של תצוגות Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index ba810bf..d94a978 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"InputFlingerの低レベルの機能を使用することをアプリに許可します。"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fiディスプレイの設定"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Wi-Fiディスプレイを設定して接続することをアプリに許可します。"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fiディスプレイの制御"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wi-Fiディスプレイの低レベル機能を制御することをアプリに許可します。"</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 5207c6a..3d46bb6 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -474,6 +474,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"앱이 InputFlinger의 하위 수준 기능을 사용하도록 합니다."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fi 디스플레이 설정"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"앱이 Wi-Fi 디스플레이를 설정하고 연결하도록 허용합니다."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi 디스플레이 제어"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"앱이 Wi-Fi 디스플레이의 하위 수준 기능을 제어하도록 허용합니다."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
@@ -1479,8 +1481,7 @@
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI 화면"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"<xliff:g id="ID">%1$d</xliff:g>번째 오버레이"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", 보안"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"무선 디스플레이가 연결되었습니다."</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"이 화면은 다른 기기에서 표시되고 있습니다."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"연결 해제"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index c57832e..b802504 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Programai leidžiama naudoti „InputFlinger“ žemo lygio funkcijas."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigūruoti „Wi-Fi“ pateiktis"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Leidžiama programai konfigūruoti ir prisijungti prie „Wi-Fi“ pateikčių."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"valdyti „Wi-Fi“ pateiktis"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Leidžiama programai valdyti „Wi-Fi“ pateikčių žemo lygio funkcijas."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index ee63fa8..479a887 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Ļauj lietotnei izmantot InputFlinger zema līmeņa funkcijas."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fi displeju konfigurēšana"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Ļauj lietotnei konfigurēt Wi-Fi displejus un veidot savienojumu ar tiem."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi displeju vadība"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Ļauj lietotnei kontrolēt zema līmeņa funkcijas Wi-Fi displejos."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index a9fe930..07aec80 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -362,10 +362,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan cetakan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"akses semua kerja cetakan"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Membenarkan pemegang mengakses kerja cetakan yang dibuat oleh apl lain. Tidak sekali-kali diperlukan untuk apl biasa."</string>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"terikat kepada perkhidmatan NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Membenarkan pemegang untuk terikat kepada aplikasi yang mengikuti kad NFC. Tidak sekali-kali harus diperlukan untuk apl normal."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"terikat kepada perkhidmatan teks"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Membenarkan pemegang mengikat kepada antara muka peringkat atasan perkhidmatan teks(mis. PerkhidmatanPenyemakEjaan). Tidak seharusnya diperlukan untuk apl biasa."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"terikat kepada perkhidmatan VPN"</string>
@@ -474,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Membenarkan apl menggunakan ciri peringkat rendah InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurasikan paparan Wifi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Membenarkan apl mengkonfigurasi dan menyambung ke paparan Wifi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kawal paparan Wifi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Membenarkan apl mengawal ciri tahap rendah paparan Wifi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
@@ -1479,8 +1479,7 @@
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Skrin HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Tindih #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", selamat"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Paparan wayarles disambungkan"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Skrin ini ditunjukkan pada peranti lain"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Putus sambungan"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 822c160..20c4778 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Lar appen bruke grunnleggende InputFlinger-funksjoner."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurere Wi-Fi-skjermer"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillater appen å konfigurere og koble til Wi-Fi-skjermer."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollere Wi-Fi-skjermer"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tillater appen å kontrollere lavnivåfunksjoner i Wi-Fi-skjermer."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 5c2b315..8399369 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Hiermee kan de app InputFlinger-functies op laag niveau gebruiken."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"wifi-displays configureren"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"De app toestaan wifi-displays te configureren en hiermee verbinding te maken."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"wifi-displays beheren"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"De app toestaan minder belangrijke functies van wifi-displays te beheren."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index cbcb059..21e3228 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Zezwala aplikacji na wykorzystanie niskopoziomowych funkcji usługi InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurowanie wyświetlaczy Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Zezwala aplikacji na konfigurację wyświetlaczy Wi-Fi i łączenie z nimi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"zarządzanie wyświetlaczami Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Zezwala aplikacji na zarządzanie niskopoziomowymi funkcjami wyświetlaczy Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 4063ebf..021ebac 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que a aplicação utilize funcionalidades de InputFlinger de nível inferior."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar visores Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que a aplicação se configure e se ligue a visores Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar visores Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que a aplicação controle funcionalidades de baixo nível em visores Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a228799..9f206a6 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -362,10 +362,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite que o proprietário use a interface de nível superior de um serviço de impressão. Não deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acessar todos os trabalhos de impressão"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite que o proprietário acesse trabalhos de impressão criados por outro aplicativo. Não deve ser necessário para aplicativos comuns."</string>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"associar ao serviço NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite ao proprietário associar a aplicativos que emulam cartões NFC. Não deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"sujeitar-se a um serviço de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite que o proprietário utilize interface de nível superior de um serviço de texto (por exemplo, SpellCheckerService). Nunca deve ser necessário para aplicativos normais."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"se ligam a um serviço de VPN"</string>
@@ -474,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que o aplicativo use recursos com baixos níveis de InputFinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar monitores Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que o aplicativo configure e conecte a monitores Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar monitores Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que o aplicativo controle recursos de baixo nível de monitores Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index c3eb2e7..e6d9783 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -773,6 +773,10 @@
     <skip />
     <!-- no translation found for permdesc_configureWifiDisplay (7916815158690218065) -->
     <skip />
+    <!-- no translation found for permlab_controlWifiDisplay (393641276723695496) -->
+    <skip />
+    <!-- no translation found for permdesc_controlWifiDisplay (4543912292681826986) -->
+    <skip />
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 6855a06..539762a 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -474,6 +474,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite aplicației să utilizeze funcțiile de nivel redus InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurează afişaje Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite aplicaţiei să configureze şi să se conecteze la afişaje Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlează afişaje Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite aplicaţiei să controleze funcţiile de nivel redus ale afişajelor Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index a5e316a..361e9a4 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -474,6 +474,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Приложение сможет использовать низкоуровневые функции InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"настраивать экраны, подключенные через Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Приложение сможет подключаться к экранам с помощью Wi-Fi и настраивать их."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Управление мониторами, подключенными через Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Приложение сможет управлять низкоуровневыми функциями экранов, подключенных через Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f4e2157..de6785c 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Umožňuje aplikácii používať funkcie nízkej úrovne aplikácie InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurovať displeje cez sieť Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Umožňuje aplikácii konfigurovať displeje a pripojiť sa k nim cez siete Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládať displeje cez sieť Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Umožňuje aplikácii ovládať základné funkcie displejov cez siete Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
@@ -1477,8 +1479,7 @@
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Obrazovka HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Prekrytie č. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", zabezpečené"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Bezdrôtový displej je pripojený"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Táto obrazovka sa zobrazuje na inom zariadení"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Odpojiť"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index c90392d..a14a080 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Aplikaciji dovoljuje uporabo funkcij InputFlinger nizke ravni."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfiguriranje zaslonov Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Omogoča aplikaciji konfiguriranje zaslonov Wi-Fi in povezovanje z njimi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"nadzor zaslonov Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Omogoča aplikaciji nadzor osnovnih funkcij zaslonov Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a33e129..1f253cf 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Дозвољава апликацији да користи InputFlinger функције ниског нивоа."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"конфигурисање Wi-Fi екрана"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозвољава апликацији да конфигурише Wi-Fi екране и повезује се са њима."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контрола Wi-Fi екрана"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Дозвољава апликацији да контролише функције Wi-Fi екрана ниског нивоа."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index aaa6b36..63ddfea 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Tillåter att appen använder lågnivåfunktioner i InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurerar Wi-Fi-skärmar"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillåter att appen konfigurerar och ansluter till Wi-Fi-skärmar."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollerar Wi-Fi-skärmar"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tillåter att appen kontrollerar grundläggande funktioner för Wi-Fi-skärmar."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
@@ -1477,8 +1479,7 @@
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-skärm"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Överlagring #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", säker"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Trådlös anslutning till skärm"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Den här skärmen visas på en annan enhet"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Koppla från"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 22c610d..0c36baf 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -362,10 +362,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Inaruhusu kishikiliaji kujifungilia kiolesura cha kiwango cha juu cha huduma ya kuchapisha. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"fikia kazi zote za kuchapisha"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Huruhusu mmiliki kufikia kazi za kuchapisha zilizoundwa na programu nyingine. Haipaswi kuhitajika kwa programu za kawaida kamwe."</string>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"funga kwa huduma ya NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Huruhusu mmiliki kufunga kwa programu zinazoiga kadi za NFC. Haipaswi kuhitaji kamwe kwa programu za kawaida."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"Imefungwa kwa huduma ya maandishi"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Inaruhusu kishikiliaji kushurutisha kusano ya kiwango cha juu ya huduma ya matini(k.m.SpellCheckerService). Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"funga kwa huduma ya VPN"</string>
@@ -474,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Inaruhusu programu kutumia vipengele vya chini vya InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"sanidi maonyesho ya Wifi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Inaruhusu programu kusanidi na kuunganika kwenye maonyesho ya Wifi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"dhibiti maonyesho ya Wifi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Inaruhusu programu kudhibiti vipengele vya kiwango cha chini vya maonyesho ya Wifi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
@@ -1479,8 +1479,7 @@
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Skrini ya HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Uwekeleaji #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", salama"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Onyesho pasiwaya limeunganishwa"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Skrini hii inaonyesha kwenye kifaa kingine"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Tenganisha"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 8f93804..d4b08c8 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"อนุญาตให้แอปใช้คุณลักษณะระดับต่ำของ InputFlinger"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"กำหนดค่าการแสดงผลด้วย WiFi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"อนุญาตให้แอปกำหนดค่าและเชื่อมต่อกับจอแสดงผล WiFi ได้"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ควบคุมการแสดงผลด้วย WiFi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"อนุญาตให้แอปควบคุมคุณลักษณะต่างๆ ในระดับล่างของการแสดงผลด้วย WiFi"</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index d5af6a7..7f33245 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Nagbibigay-daan sa app na gumamit ng mga tampok ng InputFlinger sa mababang antas."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"mag-configure ng mga Wifi display"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Pinapayagan ang app na mag-configure at kumonekta sa mga Wifi display."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"magkontrol ng mga Wifi display"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Pinapayagan ang app na magkontrol ng mga tampok sa mababang antas ng mga dispay ng Wifi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index bf002e6..d682d37 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -362,10 +362,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"İzin sahibine, bir yazdırma hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
     <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"tüm yazdırma işlerine eriş"</string>
     <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"İzin sahibine, başka uygulama tarafından oluşturulan yazdırma işlerine erişim izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC hizmetine bağla"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"İzin sahibine, NFC kartlara öykünen uygulamalara bağlama izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"kısa mesaj hizmetine bağla"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Cihazın sahibine, bir metin hizmetinin (ör. SpellCheckerService) en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerekmez."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN hizmetine bağlan"</string>
@@ -474,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Uygulamaya, alt düzey InputFlinger özelliklerini kullanma izni verir."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Kablosuz ekranları yapılandır"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Uygulamaya kablosuz ekranları yapılandırma ve bunlara bağlanma izni verir."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Kablosuz ekranları denetle"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Uygulamaya kablosuz ekranların alt düzey özelliklerini kontrol etme izni verir."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
@@ -1479,8 +1479,7 @@
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI Ekran"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Yer Paylaşımı No. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", güvenli"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Kablosuz ekrana bağlandı"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Bu ekran başka bir cihazda gösteriliyor"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Bağlantıyı kes"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 751de53..b41171b 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Дозволяє програмі використовувати низькорівневі функції InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"налаштувати екрани Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозволяє програмі налаштовувати екрани Wi-Fi і під’єднуватися до них."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"керувати екранами Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Дозволяє програмі керувати низькорівневими функціями екранів Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 56f9320..9e5b36c 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Cho phép ứng dụng sử dụng các tính năng InputFlinger cấp độ thấp."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"định cấu hình màn hình Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Cho phép ứng dụng định cấu hình và kết nối với màn hình Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kiểm soát màn hình Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Cho phép ứng dụng kiểm soát các tính năng cấp thấp của màn hình Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 161db91..a60b088 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -474,6 +474,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"允许应用使用 InputFlinger 底层功能。"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"配置 WLAN 显示设备"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允许应用配置并连接到 WLAN 显示设备。"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 WLAN 显示设备"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允许应用控制 WLAN 显示设备的基础功能。"</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index cab9de0..2ea03d7 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"允許應用程式使用 InputFlinger 的低階功能。"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"設定 Wi-Fi 顯示裝置"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允許應用程式設定及連接 Wi-Fi 顯示裝置。"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 Wi-Fi 顯示裝置"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允許應用程式控制 Wi-Fi 顯示裝置的低階功能。"</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 792d40e..2e027e1 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -472,6 +472,8 @@
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Ivumela uhlelo lokusebenza ukuthi lusebenzise izici zezinga eliphansi ze-InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"lungisa ukubukwa kwe-Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Ivumela uhlelo lokusebenza ukulungisa nokuxhuma ekubukisweni kwe-Wi-Fi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"lawula ukubukwa kwe-Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Uvumela uhlelo lokusebenza ukulawula izici zeleveli ephansi zokuboniswa kwe-Wi-Fi."</string>
     <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
     <skip />
     <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f7d0282..721bc3f 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -737,6 +737,14 @@
         <attr name="preferenceLayoutChild" format="reference" />
         <!-- Preference panel style -->
         <attr name="preferencePanelStyle" format="reference" />
+        <!-- Preference headers panel style -->
+        <attr name="preferenceHeaderPanelStyle" format="reference" />
+        <!-- Preference list style -->
+        <attr name="preferenceListStyle" format="reference" />
+        <!-- Preference fragment list style -->
+        <attr name="preferenceFragmentListStyle" format="reference" />
+        <!-- Preference fragment padding side -->
+        <attr name="preferenceFragmentPaddingSide" format="dimension" />
         <!-- Default style for switch preferences. -->
         <attr name="switchPreferenceStyle" format="reference" />
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d3dbb2a..1b5ee68 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1905,6 +1905,11 @@
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_invokeCarrierSetup">Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps.</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_accessNetworkConditions">listen for observations on network conditions</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_accessNetworkConditions">Allows an application to listen for observations on network conditions. Should never be needed for normal apps.</string>
+
     <!-- Policy administration -->
 
     <!-- Title of policy access to limiting the user's password choices -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index bd82f35..879d0f1 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1058,6 +1058,24 @@
         <item name="android:background">@null</item>
     </style>
 
+    <style name="PreferenceHeaderPanel">
+        <item name="android:layout_marginStart">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginEnd">@dimen/preference_screen_side_margin_negative</item>
+        <item name="android:paddingTop">@dimen/preference_screen_header_vertical_padding</item>
+        <item name="android:paddingBottom">@dimen/preference_screen_header_vertical_padding</item>
+    </style>
+
+    <style name="PreferenceHeaderList">
+        <item name="android:paddingStart">@dimen/preference_screen_header_padding_side</item>
+        <item name="android:paddingEnd">@dimen/preference_screen_header_padding_side</item>
+        <item name="android:scrollbarStyle">@integer/preference_screen_header_scrollbarStyle</item>
+    </style>
+
+    <style name="PreferenceFragmentList">
+        <item name="android:paddingStart">@dimen/preference_fragment_padding_side</item>
+        <item name="android:paddingEnd">@dimen/preference_fragment_padding_side</item>
+    </style>
+
     <!-- Other Misc Styles -->
     <eat-comment />
 
@@ -2426,8 +2444,8 @@
     <style name="Widget.Holo.PreferenceFrameLayout">
         <item name="android:borderTop">0dip</item>
         <item name="android:borderBottom">@dimen/preference_fragment_padding_bottom</item>
-        <item name="android:borderLeft">@dimen/preference_fragment_padding_side</item>
-        <item name="android:borderRight">@dimen/preference_fragment_padding_side</item>
+        <item name="android:borderLeft">?attr/preferenceFragmentPaddingSide</item>
+        <item name="android:borderRight">?attr/preferenceFragmentPaddingSide</item>
     </style>
 
     <!-- Pointer styles -->
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 80f7486..23bd1ca 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -311,6 +311,10 @@
         <item name="ringtonePreferenceStyle">@android:style/Preference.RingtonePreference</item>
         <item name="preferenceLayoutChild">@android:layout/preference_child</item>
         <item name="preferencePanelStyle">@style/PreferencePanel</item>
+        <item name="preferenceHeaderPanelStyle">@style/PreferenceHeaderPanel</item>
+        <item name="preferenceListStyle">@style/PreferenceHeaderList</item>
+        <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList</item>
+        <item name="preferenceFragmentPaddingSide">@dimen/preference_fragment_padding_side</item>
         <item name="detailsElementBackground">@android:drawable/panel_bg_holo_dark</item>
 
         <!-- Search widget styles -->
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index d98a538..eb8bb9f 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -100,6 +100,7 @@
             bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
         mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget);
     }
+
 private:
     Texture* const mDelegate;
 }; // struct DelegateTexture
@@ -125,12 +126,12 @@
                 y / height, (y + bitmap->height()) / height);
 
         Texture* texture = new DelegateTexture(caches, mTexture);
-        Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this);
-
         texture->id = mTexture->id;
         texture->blend = !bitmap->isOpaque();
         texture->width = bitmap->width();
         texture->height = bitmap->height();
+
+        Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this);
         texture->uvMapper = &entry->uvMapper;
 
         mEntries.add(entry->bitmap, entry);
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 9afc54d..a28efc6 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -84,11 +84,20 @@
          */
         const AssetAtlas& atlas;
 
+        /**
+         * Unique identifier used to merge bitmaps and 9-patches stored
+         * in the atlas.
+         */
+        const void* getMergeId() const {
+            return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
+        }
+
     private:
         Entry(SkBitmap* bitmap, int x, int y, bool rotated,
                 Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas):
                 bitmap(bitmap), x(x), y(y), rotated(rotated),
-                texture(texture), uvMapper(mapper), atlas(atlas) { }
+                texture(texture), uvMapper(mapper), atlas(atlas) {
+        }
 
         ~Entry() {
             delete texture;
@@ -97,7 +106,8 @@
         friend class AssetAtlas;
     };
 
-    AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0) { }
+    AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0),
+            mBlendKey(true), mOpaqueKey(false) { }
     ~AssetAtlas() { terminate(); }
 
     /**
@@ -173,6 +183,9 @@
 
     uint32_t mGenerationId;
 
+    const bool mBlendKey;
+    const bool mOpaqueKey;
+
     KeyedVector<SkBitmap*, Entry*> mEntries;
 }; // class AssetAtlas
 
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
index 6c5a847..1ef0152 100644
--- a/libs/hwui/DeferredDisplayList.h
+++ b/libs/hwui/DeferredDisplayList.h
@@ -40,7 +40,7 @@
 class DrawBatch;
 class MergingDrawBatch;
 
-typedef void* mergeid_t;
+typedef const void* mergeid_t;
 
 class DeferredDisplayList {
 public:
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 83de651..1b52b65 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -818,7 +818,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) &mEntry->atlas : (mergeid_t) mBitmap;
+        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
 
         // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
         // MergingDrawBatch::canMergeWith()
@@ -1071,7 +1071,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
-        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) &mEntry->atlas : (mergeid_t) mBitmap;
+        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
         deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
                 OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
         deferInfo.opaqueOverBounds = isOpaqueOverBounds() && mBitmap->isOpaque();
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index aa3c530..d20f5b9 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -87,7 +87,7 @@
     private static final int AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED    = -20;
 
     // Events:
-    // to keep in sync with frameworks/base/include/media/AudioRecord.h
+    // to keep in sync with frameworks/av/include/media/AudioRecord.h
     /**
      * Event id denotes when record head has reached a previously set marker.
      */
@@ -427,10 +427,12 @@
 
     /**
      * Returns the minimum buffer size required for the successful creation of an AudioRecord
-     * object.
+     * object, in byte units.
      * Note that this size doesn't guarantee a smooth recording under load, and higher values
      * should be chosen according to the expected frequency at which the AudioRecord instance
      * will be polled for new data.
+     * See {@link #AudioRecord(int, int, int, int, int)} for more information on valid
+     * configuration values.
      * @param sampleRateInHz the sample rate expressed in Hertz.
      * @param channelConfig describes the configuration of the audio channels.
      *   See {@link AudioFormat#CHANNEL_IN_MONO} and
@@ -440,10 +442,9 @@
      * @return {@link #ERROR_BAD_VALUE} if the recording parameters are not supported by the
      *  hardware, or an invalid parameter was passed,
      *  or {@link #ERROR} if the implementation was unable to query the hardware for its
-     *  output properties,
+     *  input properties,
      *   or the minimum buffer size expressed in bytes.
-     * @see #AudioRecord(int, int, int, int, int) for more information on valid
-     *   configuration values.
+     * @see #AudioRecord(int, int, int, int, int)
      */
     static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
         int channelCount = 0;
@@ -692,6 +693,7 @@
      * Sets the period at which the listener is called, if set with
      * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or
      * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}.
+     * It is possible for notifications to be lost if the period is too small.
      * @param periodInFrames update period expressed in frames
      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}
      */
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index c8dffcd..d9227bd 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -166,7 +166,7 @@
     private int mNativeBufferSizeInBytes = 0;
     private int mNativeBufferSizeInFrames = 0;
     /**
-     * Handler for marker events coming from the native code.
+     * Handler for events coming from the native code.
      */
     private NativeEventHandlerDelegate mEventHandlerDelegate;
     /**
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 8cf0b4b..703eb27 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -300,6 +300,24 @@
             mErrorCode = errorCode;
         }
 
+        /**
+         * This indicates that no key has been set to perform the requested
+         * decrypt operation.
+         */
+        public static final int ERROR_NO_KEY = 1;
+
+        /**
+         * This indicates that the key used for decryption is no longer
+         * valid due to license term expiration.
+         */
+        public static final int ERROR_KEY_EXPIRED = 2;
+
+        /**
+         * This indicates that a required crypto resource was not able to be
+         * allocated while attempting the requested operation.
+         */
+        public static final int ERROR_RESOURCE_BUSY = 3;
+
         public int getErrorCode() {
             return mErrorCode;
         }
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 7677d8a1..cd97ad9 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -273,6 +273,7 @@
      * Open a new session with the MediaDrm object.  A session ID is returned.
      *
      * @throws NotProvisionedException if provisioning is needed
+     * @throws ResourceBusyException if required resources are in use
      */
     public native byte[] openSession() throws NotProvisionedException;
 
@@ -379,6 +380,7 @@
      * reprovisioning is required
      * @throws DeniedByServerException if the response indicates that the
      * server rejected the request
+     * @throws ResourceBusyException if required resources are in use
      */
     public native byte[] provideKeyResponse(byte[] scope, byte[] response)
         throws NotProvisionedException, DeniedByServerException;
diff --git a/media/java/android/media/ResourceBusyException.java b/media/java/android/media/ResourceBusyException.java
new file mode 100644
index 0000000..a5abe21
--- /dev/null
+++ b/media/java/android/media/ResourceBusyException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * Exception thrown when an operation on a MediaDrm object is attempted
+ * and hardware resources are not available, due to being in use.
+ */
+public final class ResourceBusyException extends MediaDrmException {
+    public ResourceBusyException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index cd1d9ce..8689e19 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -49,9 +49,14 @@
     DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED     = -3,
 };
 
+struct CryptoErrorCodes {
+    jint cryptoErrorNoKey;
+    jint cryptoErrorKeyExpired;
+    jint cryptoErrorResourceBusy;
+} gCryptoErrorCodes;
+
 struct fields_t {
     jfieldID context;
-
     jfieldID cryptoInfoNumSubSamplesID;
     jfieldID cryptoInfoNumBytesOfClearDataID;
     jfieldID cryptoInfoNumBytesOfEncryptedDataID;
@@ -342,6 +347,21 @@
 
     jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error");
 
+    /* translate OS errors to Java API CryptoException errorCodes */
+    switch (err) {
+        case ERROR_DRM_NO_LICENSE:
+            err = gCryptoErrorCodes.cryptoErrorNoKey;
+            break;
+        case ERROR_DRM_LICENSE_EXPIRED:
+            err = gCryptoErrorCodes.cryptoErrorKeyExpired;
+            break;
+        case ERROR_DRM_RESOURCE_BUSY:
+            err = gCryptoErrorCodes.cryptoErrorResourceBusy;
+            break;
+        default:
+            break;
+    }
+
     jthrowable exception =
         (jthrowable)env->NewObject(clazz, constructID, err, msgObj);
 
@@ -350,9 +370,8 @@
 
 static jint throwExceptionAsNecessary(
         JNIEnv *env, status_t err, const char *msg = NULL) {
-    if (err >= ERROR_DRM_WV_VENDOR_MIN && err <= ERROR_DRM_WV_VENDOR_MAX) {
+    if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) {
         // We'll throw our custom MediaCodec.CryptoException
-
         throwCryptoException(env, err, msg);
         return 0;
     }
@@ -370,6 +389,12 @@
         case INFO_OUTPUT_BUFFERS_CHANGED:
             return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED;
 
+        case ERROR_DRM_NO_LICENSE:
+        case ERROR_DRM_LICENSE_EXPIRED:
+        case ERROR_DRM_RESOURCE_BUSY:
+            throwCryptoException(env, err, msg);
+            break;
+
         default:
         {
             jniThrowException(env, "java/lang/IllegalStateException", msg);
@@ -852,6 +877,22 @@
 
     gFields.cryptoInfoModeID = env->GetFieldID(clazz, "mode", "I");
     CHECK(gFields.cryptoInfoModeID != NULL);
+
+    clazz = env->FindClass("android/media/MediaCodec$CryptoException");
+    CHECK(clazz != NULL);
+
+    jfieldID field;
+    field = env->GetStaticFieldID(clazz, "ERROR_NO_KEY", "I");
+    CHECK(field != NULL);
+    gCryptoErrorCodes.cryptoErrorNoKey = env->GetStaticIntField(clazz, field);
+
+    field = env->GetStaticFieldID(clazz, "ERROR_KEY_EXPIRED", "I");
+    CHECK(field != NULL);
+    gCryptoErrorCodes.cryptoErrorKeyExpired = env->GetStaticIntField(clazz, field);
+
+    field = env->GetStaticFieldID(clazz, "ERROR_RESOURCE_BUSY", "I");
+    CHECK(field != NULL);
+    gCryptoErrorCodes.cryptoErrorResourceBusy = env->GetStaticIntField(clazz, field);
 }
 
 static void android_media_MediaCodec_native_setup(
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 7799ca4..16a1e48 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -242,6 +242,9 @@
     } else if (err == ERROR_DRM_NOT_PROVISIONED) {
         jniThrowException(env, "android/media/NotProvisionedException", msg);
         return true;
+    } else if (err == ERROR_DRM_RESOURCE_BUSY) {
+        jniThrowException(env, "android/media/ResourceBusyException", msg);
+        return true;
     } else if (err == ERROR_DRM_DEVICE_REVOKED) {
         jniThrowException(env, "android/media/DeniedByServerException", msg);
         return true;
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index b88099e..1d97161 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -3,7 +3,10 @@
 
     <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
 
-    <application android:label="@string/app_label">
+    <application
+        android:label="@string/app_label"
+        android:supportsRtl="true">
+
         <activity
             android:name=".DocumentsActivity"
             android:finishOnCloseSystemDialogs="true"
diff --git a/packages/DocumentsUI/res/layout/fragment_roots.xml b/packages/DocumentsUI/res/layout/fragment_roots.xml
index d772892..09782d9 100644
--- a/packages/DocumentsUI/res/layout/fragment_roots.xml
+++ b/packages/DocumentsUI/res/layout/fragment_roots.xml
@@ -17,4 +17,5 @@
 <ListView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/list"
     android:layout_width="match_parent"
-    android:layout_height="match_parent" />
+    android:layout_height="match_parent"
+    android:divider="@null" />
diff --git a/packages/DocumentsUI/res/layout/item_doc_grid.xml b/packages/DocumentsUI/res/layout/item_doc_grid.xml
index caa9db6..ad8f51c 100644
--- a/packages/DocumentsUI/res/layout/item_doc_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_doc_grid.xml
@@ -16,7 +16,7 @@
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="140dip"
+    android:layout_height="160dip"
     android:paddingBottom="?android:attr/listPreferredItemPaddingEnd"
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
 
@@ -27,16 +27,16 @@
         android:foreground="@drawable/item_background"
         android:duplicateParentState="true">
 
-        <GridLayout
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:columnCount="1">
+            android:orientation="vertical">
 
             <ImageView
                 android:id="@android:id/icon"
                 android:layout_width="match_parent"
                 android:layout_height="0dip"
-                android:layout_gravity="fill_vertical"
+                android:layout_weight="1"
                 android:background="#bbb"
                 android:scaleType="centerInside"
                 android:contentDescription="@null" />
@@ -44,16 +44,67 @@
             <TextView
                 android:id="@android:id/title"
                 android:layout_width="match_parent"
-                android:layout_marginStart="8dip"
-                android:layout_marginEnd="8dip"
-                android:layout_marginTop="8dip"
-                android:layout_marginBottom="8dip"
+                android:layout_height="wrap_content"
                 android:singleLine="true"
                 android:ellipsize="marquee"
+                android:paddingTop="6dp"
+                android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+                android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
                 android:textAppearance="?android:attr/textAppearanceSmall"
                 android:textAlignment="viewStart" />
 
-        </GridLayout>
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:paddingBottom="6dp"
+                android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+                android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+                <ImageView
+                    android:id="@android:id/icon1"
+                    android:layout_width="24dip"
+                    android:layout_height="24dip"
+                    android:layout_marginEnd="6dip"
+                    android:scaleType="centerInside"
+                    android:contentDescription="@null" />
+
+                <TextView
+                    android:id="@android:id/summary"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_gravity="center_vertical"
+                    android:layout_marginEnd="8dp"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:textAlignment="viewStart"
+                    android:textAppearance="?android:attr/textAppearanceSmall" />
+
+                <TextView
+                    android:id="@+id/size"
+                    android:layout_width="70dp"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    android:layout_marginEnd="8dp"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:textAlignment="viewEnd"
+                    android:textAppearance="?android:attr/textAppearanceSmall" />
+
+                <TextView
+                    android:id="@+id/date"
+                    android:layout_width="70dp"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:textAlignment="viewEnd"
+                    android:textAppearance="?android:attr/textAppearanceSmall" />
+
+            </LinearLayout>
+
+        </LinearLayout>
 
     </FrameLayout>
 
diff --git a/packages/DocumentsUI/res/layout/item_doc_list.xml b/packages/DocumentsUI/res/layout/item_doc_list.xml
index 39e55be..bb27173 100644
--- a/packages/DocumentsUI/res/layout/item_doc_list.xml
+++ b/packages/DocumentsUI/res/layout/item_doc_list.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@drawable/item_background"
@@ -23,40 +23,82 @@
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
     android:paddingTop="8dip"
     android:paddingBottom="8dip"
-    android:columnCount="3">
+    android:orientation="horizontal">
 
     <ImageView
         android:id="@android:id/icon"
         android:layout_width="@android:dimen/app_icon_size"
         android:layout_height="@android:dimen/app_icon_size"
-        android:layout_rowSpan="2"
         android:layout_marginEnd="8dip"
+        android:layout_gravity="center_vertical"
         android:scaleType="centerInside"
         android:contentDescription="@null" />
 
-    <TextView
-        android:id="@android:id/title"
+    <LinearLayout
         android:layout_width="0dip"
-        android:layout_gravity="fill_horizontal"
-        android:layout_marginTop="2dip"
-        android:layout_columnSpan="2"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textAlignment="viewStart" />
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:layout_gravity="center_vertical"
+        android:orientation="vertical">
 
-    <ImageView
-        android:id="@android:id/icon1"
-        android:layout_width="24dip"
-        android:layout_height="24dip"
-        android:layout_marginEnd="8dip"
-        android:visibility="gone"
-        android:scaleType="centerInside"
-        android:contentDescription="@null" />
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textAlignment="viewStart" />
 
-    <TextView
-        android:id="@android:id/summary"
-        android:layout_marginTop="2dip"
-        android:textAppearance="?android:attr/textAppearanceSmall" />
+        <LinearLayout
+            android:id="@+id/line2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
 
-</GridLayout>
+            <ImageView
+                android:id="@android:id/icon1"
+                android:layout_width="24dip"
+                android:layout_height="24dip"
+                android:layout_marginEnd="6dip"
+                android:scaleType="centerInside"
+                android:contentDescription="@null" />
+
+            <TextView
+                android:id="@android:id/summary"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_gravity="center_vertical"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewStart"
+                android:textAppearance="?android:attr/textAppearanceSmall" />
+
+            <TextView
+                android:id="@+id/size"
+                android:layout_width="70dp"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewEnd"
+                android:textAppearance="?android:attr/textAppearanceSmall" />
+
+            <TextView
+                android:id="@+id/date"
+                android:layout_width="70dp"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewEnd"
+                android:textAppearance="?android:attr/textAppearanceSmall" />
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/menu/activity.xml b/packages/DocumentsUI/res/menu/activity.xml
index a0d03b2..d57f88a 100644
--- a/packages/DocumentsUI/res/menu/activity.xml
+++ b/packages/DocumentsUI/res/menu/activity.xml
@@ -27,4 +27,14 @@
         android:showAsAction="always|collapseActionView"
         android:actionViewClass="android.widget.SearchView"
         android:imeOptions="actionSearch" />
+    <item
+        android:id="@+id/menu_grid"
+        android:title="@string/menu_grid"
+        android:icon="@drawable/ic_menu_grid"
+        android:showAsAction="ifRoom" />
+    <item
+        android:id="@+id/menu_list"
+        android:title="@string/menu_list"
+        android:icon="@drawable/ic_menu_list"
+        android:showAsAction="ifRoom" />
 </menu>
diff --git a/packages/DocumentsUI/res/menu/directory.xml b/packages/DocumentsUI/res/menu/directory.xml
deleted file mode 100644
index 12d0324..0000000
--- a/packages/DocumentsUI/res/menu/directory.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:id="@+id/menu_grid"
-        android:title="@string/menu_grid"
-        android:icon="@drawable/ic_menu_grid"
-        android:showAsAction="ifRoom" />
-    <item
-        android:id="@+id/menu_list"
-        android:title="@string/menu_list"
-        android:icon="@drawable/ic_menu_list"
-        android:showAsAction="ifRoom" />
-</menu>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 1443f26..d986a51 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -26,11 +26,12 @@
 import android.os.Bundle;
 import android.provider.DocumentsContract;
 import android.text.format.DateUtils;
+import android.text.format.Formatter;
+import android.util.Log;
 import android.util.SparseBooleanArray;
 import android.view.ActionMode;
 import android.view.LayoutInflater;
 import android.view.Menu;
-import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
@@ -46,20 +47,21 @@
 
 import com.android.documentsui.DocumentsActivity.DisplayState;
 import com.android.documentsui.model.Document;
+import com.android.documentsui.model.Root;
 import com.android.internal.util.Predicate;
 import com.google.android.collect.Lists;
 
+import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Display the documents inside a single directory.
  */
 public class DirectoryFragment extends Fragment {
 
-    // TODO: show storage backend in item views when requested
-
     private ListView mListView;
     private GridView mGridView;
 
@@ -68,19 +70,35 @@
     public static final int TYPE_NORMAL = 1;
     public static final int TYPE_SEARCH = 2;
     public static final int TYPE_RECENT_OPEN = 3;
-    public static final int TYPE_RECENT_CREATE = 4;
 
     private int mType = TYPE_NORMAL;
 
     private DocumentsAdapter mAdapter;
     private LoaderCallbacks<List<Document>> mCallbacks;
 
+    private static final String EXTRA_TYPE = "type";
     private static final String EXTRA_URI = "uri";
 
-    private static final int LOADER_DOCUMENTS = 2;
+    private static AtomicInteger sLoaderId = new AtomicInteger(4000);
 
-    public static void show(FragmentManager fm, Uri uri) {
+    private final int mLoaderId = sLoaderId.incrementAndGet();
+
+    public static void showNormal(FragmentManager fm, Uri uri) {
+        show(fm, TYPE_NORMAL, uri);
+    }
+
+    public static void showSearch(FragmentManager fm, Uri uri, String query) {
+        final Uri searchUri = DocumentsContract.buildSearchUri(uri, query);
+        show(fm, TYPE_SEARCH, searchUri);
+    }
+
+    public static void showRecentsOpen(FragmentManager fm) {
+        show(fm, TYPE_RECENT_OPEN, null);
+    }
+
+    private static void show(FragmentManager fm, int type, Uri uri) {
         final Bundle args = new Bundle();
+        args.putInt(EXTRA_TYPE, type);
         args.putParcelable(EXTRA_URI, uri);
 
         final DirectoryFragment fragment = new DirectoryFragment();
@@ -97,12 +115,6 @@
     }
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setHasOptionsMenu(true);
-    }
-
-    @Override
     public View onCreateView(
             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         final Context context = inflater.getContext();
@@ -118,19 +130,9 @@
         mGridView.setMultiChoiceModeListener(mMultiListener);
 
         mAdapter = new DocumentsAdapter();
-        updateMode();
 
         final Uri uri = getArguments().getParcelable(EXTRA_URI);
-
-        if (uri.getQueryParameter(DocumentsContract.PARAM_QUERY) != null) {
-            mType = TYPE_SEARCH;
-        } else if (RecentsProvider.buildRecentOpen().equals(uri)) {
-            mType = TYPE_RECENT_OPEN;
-        } else if (RecentsProvider.buildRecentCreate().equals(uri)) {
-            mType = TYPE_RECENT_CREATE;
-        } else {
-            mType = TYPE_NORMAL;
-        }
+        mType = getArguments().getInt(EXTRA_TYPE);
 
         mCallbacks = new LoaderCallbacks<List<Document>>() {
             @Override
@@ -140,6 +142,8 @@
                 final Uri contentsUri;
                 if (mType == TYPE_NORMAL) {
                     contentsUri = DocumentsContract.buildContentsUri(uri);
+                } else if (mType == TYPE_RECENT_OPEN) {
+                    contentsUri = RecentsProvider.buildRecentOpen();
                 } else {
                     contentsUri = uri;
                 }
@@ -147,8 +151,7 @@
                 final Predicate<Document> filter = new MimePredicate(state.acceptMimes);
 
                 final Comparator<Document> sortOrder;
-                if (state.sortOrder == DisplayState.SORT_ORDER_DATE || mType == TYPE_RECENT_OPEN
-                        || mType == TYPE_RECENT_CREATE) {
+                if (state.sortOrder == DisplayState.SORT_ORDER_DATE || mType == TYPE_RECENT_OPEN) {
                     sortOrder = new Document.DateComparator();
                 } else if (state.sortOrder == DisplayState.SORT_ORDER_NAME) {
                     sortOrder = new Document.NameComparator();
@@ -170,56 +173,30 @@
             }
         };
 
+        updateDisplayState();
+
         return view;
     }
 
     @Override
     public void onStart() {
         super.onStart();
-        getLoaderManager().restartLoader(LOADER_DOCUMENTS, getArguments(), mCallbacks);
+        getLoaderManager().restartLoader(mLoaderId, getArguments(), mCallbacks);
     }
 
     @Override
     public void onStop() {
         super.onStop();
-        getLoaderManager().destroyLoader(LOADER_DOCUMENTS);
+        getLoaderManager().destroyLoader(mLoaderId);
     }
 
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        super.onCreateOptionsMenu(menu, inflater);
-        inflater.inflate(R.menu.directory, menu);
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        super.onPrepareOptionsMenu(menu);
+    public void updateDisplayState() {
         final DisplayState state = getDisplayState(this);
-        menu.findItem(R.id.menu_grid).setVisible(state.mode != DisplayState.MODE_GRID);
-        menu.findItem(R.id.menu_list).setVisible(state.mode != DisplayState.MODE_LIST);
-    }
 
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        final DisplayState state = getDisplayState(this);
-        final int id = item.getItemId();
-        if (id == R.id.menu_grid) {
-            state.mode = DisplayState.MODE_GRID;
-            updateMode();
-            getFragmentManager().invalidateOptionsMenu();
-            return true;
-        } else if (id == R.id.menu_list) {
-            state.mode = DisplayState.MODE_LIST;
-            updateMode();
-            getFragmentManager().invalidateOptionsMenu();
-            return true;
-        } else {
-            return super.onOptionsItemSelected(item);
-        }
-    }
-
-    private void updateMode() {
-        final DisplayState state = getDisplayState(this);
+        // TODO: avoid kicking loader when sort didn't change
+        getLoaderManager().restartLoader(mLoaderId, getArguments(), mCallbacks);
+        mListView.smoothScrollToPosition(0);
+        mGridView.smoothScrollToPosition(0);
 
         mListView.setVisibility(state.mode == DisplayState.MODE_LIST ? View.VISIBLE : View.GONE);
         mGridView.setVisibility(state.mode == DisplayState.MODE_GRID ? View.VISIBLE : View.GONE);
@@ -250,12 +227,6 @@
         }
     }
 
-    public void updateSortOrder() {
-        getLoaderManager().restartLoader(LOADER_DOCUMENTS, getArguments(), mCallbacks);
-        mListView.smoothScrollToPosition(0);
-        mGridView.smoothScrollToPosition(0);
-    }
-
     private OnItemClickListener mItemListener = new OnItemClickListener() {
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@@ -309,7 +280,7 @@
             if (checked) {
                 // Directories cannot be checked
                 final Document doc = mAdapter.getItem(position);
-                if (DocumentsContract.MIME_TYPE_DIRECTORY.equals(doc.mimeType)) {
+                if (doc.isDirectory()) {
                     mCurrentView.setItemChecked(position, false);
                 }
             }
@@ -337,10 +308,10 @@
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             final Context context = parent.getContext();
+            final DisplayState state = getDisplayState(DirectoryFragment.this);
 
             if (convertView == null) {
                 final LayoutInflater inflater = LayoutInflater.from(context);
-                final DisplayState state = getDisplayState(DirectoryFragment.this);
                 if (state.mode == DisplayState.MODE_LIST) {
                     convertView = inflater.inflate(R.layout.item_doc_list, parent, false);
                 } else if (state.mode == DisplayState.MODE_GRID) {
@@ -352,9 +323,12 @@
 
             final Document doc = getItem(position);
 
-            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
-            final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
             final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1);
+            final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
+            final TextView date = (TextView) convertView.findViewById(R.id.date);
+            final TextView size = (TextView) convertView.findViewById(R.id.size);
 
             if (doc.isThumbnailSupported()) {
                 // TODO: load thumbnails async
@@ -365,8 +339,37 @@
             }
 
             title.setText(doc.displayName);
-            if (summary != null) {
-                summary.setText(DateUtils.getRelativeTimeSpanString(doc.lastModified));
+
+            if (mType == TYPE_NORMAL || mType == TYPE_SEARCH) {
+                icon1.setVisibility(View.GONE);
+                if (doc.summary != null) {
+                    summary.setText(doc.summary);
+                    summary.setVisibility(View.VISIBLE);
+                } else {
+                    summary.setVisibility(View.INVISIBLE);
+                }
+            } else if (mType == TYPE_RECENT_OPEN) {
+                final Root root = RootsCache.findRoot(context, doc);
+                icon1.setVisibility(View.VISIBLE);
+                icon1.setImageDrawable(root.icon);
+                summary.setText(root.getDirectoryString());
+                summary.setVisibility(View.VISIBLE);
+            }
+
+            // TODO: omit year from format
+            date.setText(DateUtils.formatSameDayTime(
+                    doc.lastModified, System.currentTimeMillis(), DateFormat.SHORT,
+                    DateFormat.SHORT));
+
+            if (state.showSize) {
+                size.setVisibility(View.VISIBLE);
+                if (doc.isDirectory()) {
+                    size.setText(null);
+                } else {
+                    size.setText(Formatter.formatFileSize(context, doc.size));
+                }
+            } else {
+                size.setVisibility(View.GONE);
             }
 
             return convertView;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 6067581..6784d709d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -28,7 +28,6 @@
 import android.graphics.drawable.ColorDrawable;
 import android.net.Uri;
 import android.os.Bundle;
-import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.DocumentColumns;
 import android.support.v4.app.ActionBarDrawerToggle;
 import android.support.v4.view.GravityCompat;
@@ -42,27 +41,23 @@
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
 import android.widget.SearchView;
+import android.widget.SearchView.OnCloseListener;
 import android.widget.SearchView.OnQueryTextListener;
 import android.widget.TextView;
 import android.widget.Toast;
 
 import com.android.documentsui.model.Document;
+import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.Root;
 
-import org.json.JSONArray;
-import org.json.JSONException;
-
 import java.util.Arrays;
-import java.util.LinkedList;
 import java.util.List;
 
 public class DocumentsActivity extends Activity {
     public static final String TAG = "Documents";
 
-    // TODO: share backend root cache with recents provider
-
-    private static final int ACTION_OPEN = 1;
-    private static final int ACTION_CREATE = 2;
+    public static final int ACTION_OPEN = 1;
+    public static final int ACTION_CREATE = 2;
 
     private int mAction;
 
@@ -72,11 +67,12 @@
     private DrawerLayout mDrawerLayout;
     private ActionBarDrawerToggle mDrawerToggle;
 
-    private Root mCurrentRoot;
-
     private final DisplayState mDisplayState = new DisplayState();
 
-    private LinkedList<Document> mStack = new LinkedList<Document>();
+    /** Current user navigation stack; empty implies recents. */
+    private DocumentStack mStack;
+    /** Currently active search, overriding any stack. */
+    private String mCurrentSearch;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -135,19 +131,14 @@
                 .query(RecentsProvider.buildResume(packageName), null, null, null, null);
         try {
             if (cursor.moveToFirst()) {
-                final String rawStack = cursor.getString(
+                final String raw = cursor.getString(
                         cursor.getColumnIndex(RecentsProvider.COL_PATH));
-                restoreStack(rawStack);
+                mStack = DocumentStack.deserialize(getContentResolver(), raw);
             }
         } finally {
             cursor.close();
         }
 
-        // Start in recents if no restored stack
-        if (mStack.isEmpty()) {
-            onRootPicked(RootsCache.getRecentOpenRoot(this), false);
-        }
-
         updateDirectoryFragment();
     }
 
@@ -201,7 +192,7 @@
             final Root root = getCurrentRoot();
             actionBar.setIcon(root != null ? root.icon : null);
 
-            if (getCurrentRoot().isRecents) {
+            if (root.isRecents) {
                 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
                 actionBar.setTitle(root.title);
             } else {
@@ -229,10 +220,8 @@
         mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
             @Override
             public boolean onQueryTextSubmit(String query) {
-                // TODO: use second directory stack for searches?
-                final Document cwd = getCurrentDirectory();
-                final Document searchDoc = Document.fromSearch(cwd.uri, query);
-                onDocumentPicked(searchDoc);
+                mCurrentSearch = query;
+                updateDirectoryFragment();
                 mSearchView.setIconified(true);
                 return true;
             }
@@ -243,6 +232,15 @@
             }
         });
 
+        mSearchView.setOnCloseListener(new OnCloseListener() {
+            @Override
+            public boolean onClose() {
+                mCurrentSearch = null;
+                updateDirectoryFragment();
+                return false;
+            }
+        });
+
         return true;
     }
 
@@ -265,6 +263,9 @@
             SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
         }
 
+        menu.findItem(R.id.menu_grid).setVisible(mDisplayState.mode != DisplayState.MODE_GRID);
+        menu.findItem(R.id.menu_list).setVisible(mDisplayState.mode != DisplayState.MODE_LIST);
+
         return true;
     }
 
@@ -283,8 +284,19 @@
             return true;
         } else if (id == R.id.menu_search) {
             return false;
+        } else if (id == R.id.menu_grid) {
+            mDisplayState.mode = DisplayState.MODE_GRID;
+            updateDisplayState();
+            invalidateOptionsMenu();
+            return true;
+        } else if (id == R.id.menu_list) {
+            mDisplayState.mode = DisplayState.MODE_LIST;
+            updateDisplayState();
+            invalidateOptionsMenu();
+            return true;
+        } else {
+            return super.onOptionsItemSelected(item);
         }
-        return super.onOptionsItemSelected(item);
     }
 
     @Override
@@ -339,7 +351,8 @@
             if (cwd != null) {
                 title.setText(cwd.displayName);
             } else {
-                title.setText(null);
+                // No directory means recents
+                title.setText(R.string.root_recent);
             }
 
             summary.setText((String) getItem(position));
@@ -365,13 +378,18 @@
         @Override
         public boolean onNavigationItemSelected(int itemPosition, long itemId) {
             mDisplayState.sortOrder = itemPosition;
-            DirectoryFragment.get(getFragmentManager()).updateSortOrder();
+            updateDisplayState();
             return true;
         }
     };
 
     public Root getCurrentRoot() {
-        return mCurrentRoot;
+        final Document cwd = getCurrentDirectory();
+        if (cwd != null) {
+            return RootsCache.findRoot(this, cwd);
+        } else {
+            return RootsCache.getRecentsRoot(this);
+        }
     }
 
     public Document getCurrentDirectory() {
@@ -385,19 +403,47 @@
     private void updateDirectoryFragment() {
         final FragmentManager fm = getFragmentManager();
         final Document cwd = getCurrentDirectory();
-        if (cwd != null) {
-            DirectoryFragment.show(fm, cwd.uri);
+        if (cwd == null) {
+            // No directory means recents
+            if (mAction == ACTION_CREATE) {
+                RecentsCreateFragment.show(fm);
+            } else {
+                DirectoryFragment.showRecentsOpen(fm);
+            }
+        } else {
+            if (mCurrentSearch != null) {
+                // Ongoing search
+                DirectoryFragment.showSearch(fm, cwd.uri, mCurrentSearch);
+            } else {
+                // Normal boring directory
+                DirectoryFragment.showNormal(fm, cwd.uri);
+            }
         }
+
         updateActionBar();
         invalidateOptionsMenu();
         dumpStack();
     }
 
+    private void updateDisplayState() {
+        // TODO: handle multiple directory stacks on tablets
+        DirectoryFragment.get(getFragmentManager()).updateDisplayState();
+    }
+
+    public void onStackPicked(DocumentStack stack) {
+        mStack = stack;
+        updateDirectoryFragment();
+    }
+
     public void onRootPicked(Root root, boolean closeDrawer) {
         // Clear entire backstack and start in new root
         mStack.clear();
-        mCurrentRoot = root;
-        onDocumentPicked(Document.fromRoot(getContentResolver(), root));
+
+        if (!root.isRecents) {
+            onDocumentPicked(Document.fromRoot(getContentResolver(), root));
+        } else {
+            updateDirectoryFragment();
+        }
 
         if (closeDrawer) {
             mDrawerLayout.closeDrawers();
@@ -406,7 +452,7 @@
 
     public void onDocumentPicked(Document doc) {
         final FragmentManager fm = getFragmentManager();
-        if (DocumentsContract.MIME_TYPE_DIRECTORY.equals(doc.mimeType)) {
+        if (doc.isDirectory()) {
             mStack.push(doc);
             updateDirectoryFragment();
         } else if (mAction == ACTION_OPEN) {
@@ -443,52 +489,17 @@
         }
     }
 
-    private String saveStack() {
-        if (mCurrentRoot.isRecents) return null;
-
-        final JSONArray stack = new JSONArray();
-        for (int i = 0; i < mStack.size(); i++) {
-            stack.put(mStack.get(i).uri);
-        }
-        return stack.toString();
-    }
-
-    private void restoreStack(String rawStack) {
-        Log.d(TAG, "restoreStack: " + rawStack);
-        mStack.clear();
-
-        if (rawStack == null) return;
-        try {
-            final JSONArray stack = new JSONArray(rawStack);
-            for (int i = 0; i < stack.length(); i++) {
-                final Uri uri = Uri.parse(stack.getString(i));
-                final Document doc = Document.fromUri(getContentResolver(), uri);
-                mStack.add(doc);
-            }
-        } catch (JSONException e) {
-            Log.w(TAG, "Failed to decode stack", e);
-        }
-
-        // TODO: handle roots that have gone missing
-        final Document cwd = getCurrentDirectory();
-        if (cwd != null) {
-            final String authority = cwd.uri.getAuthority();
-            final String rootId = DocumentsContract.getRootId(cwd.uri);
-            mCurrentRoot = RootsCache.findRoot(this, authority, rootId);
-        }
-    }
-
     private void onFinished(Uri... uris) {
         Log.d(TAG, "onFinished() " + Arrays.toString(uris));
 
         final ContentResolver resolver = getContentResolver();
         final ContentValues values = new ContentValues();
 
-        final String stack = saveStack();
+        final String rawStack = DocumentStack.serialize(mStack);
         if (mAction == ACTION_CREATE) {
             // Remember stack for last create
             values.clear();
-            values.put(RecentsProvider.COL_PATH, stack);
+            values.put(RecentsProvider.COL_PATH, rawStack);
             resolver.insert(RecentsProvider.buildRecentCreate(), values);
 
         } else if (mAction == ACTION_OPEN) {
@@ -503,7 +514,7 @@
         // Remember location for next app launch
         final String packageName = getCallingPackage();
         values.clear();
-        values.put(RecentsProvider.COL_PATH, stack);
+        values.put(RecentsProvider.COL_PATH, rawStack);
         resolver.insert(RecentsProvider.buildResume(packageName), values);
 
         final Intent intent = new Intent();
@@ -532,6 +543,7 @@
         public String[] acceptMimes;
         public int sortOrder = SORT_ORDER_NAME;
         public boolean allowMultiple = false;
+        public boolean showSize = false;
 
         public static final int MODE_LIST = 0;
         public static final int MODE_GRID = 1;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
index 0d2f381..f945c6a0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
@@ -16,8 +16,6 @@
 
 package com.android.documentsui;
 
-import android.provider.DocumentsContract;
-
 import com.android.documentsui.model.Document;
 import com.android.internal.util.Predicate;
 
@@ -30,7 +28,7 @@
 
     @Override
     public boolean apply(Document doc) {
-        if (DocumentsContract.MIME_TYPE_DIRECTORY.equals(doc.mimeType)) {
+        if (doc.isDirectory()) {
             return true;
         }
         for (String filter : mFilters) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
new file mode 100644
index 0000000..2651e4c
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Loader;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.text.TextUtils.TruncateAt;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.Root;
+import com.google.android.collect.Lists;
+
+import libcore.io.IoUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Display directories where recent creates took place.
+ */
+public class RecentsCreateFragment extends Fragment {
+
+    private ListView mListView;
+
+    private DocumentStackAdapter mAdapter;
+    private LoaderCallbacks<List<DocumentStack>> mCallbacks;
+
+    private static final int LOADER_RECENTS = 3;
+
+    public static void show(FragmentManager fm) {
+        final RecentsCreateFragment fragment = new RecentsCreateFragment();
+        final FragmentTransaction ft = fm.beginTransaction();
+        ft.replace(R.id.container_directory, fragment);
+        ft.commitAllowingStateLoss();
+    }
+
+    @Override
+    public View onCreateView(
+            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        final Context context = inflater.getContext();
+
+        final View view = inflater.inflate(R.layout.fragment_directory, container, false);
+
+        mListView = (ListView) view.findViewById(R.id.list);
+        mListView.setOnItemClickListener(mItemListener);
+
+        mAdapter = new DocumentStackAdapter();
+        mListView.setAdapter(mAdapter);
+
+        mCallbacks = new LoaderCallbacks<List<DocumentStack>>() {
+            @Override
+            public Loader<List<DocumentStack>> onCreateLoader(int id, Bundle args) {
+                return new RecentsCreateLoader(context);
+            }
+
+            @Override
+            public void onLoadFinished(
+                    Loader<List<DocumentStack>> loader, List<DocumentStack> data) {
+                mAdapter.swapStacks(data);
+            }
+
+            @Override
+            public void onLoaderReset(Loader<List<DocumentStack>> loader) {
+                mAdapter.swapStacks(null);
+            }
+        };
+
+        return view;
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        getLoaderManager().restartLoader(LOADER_RECENTS, getArguments(), mCallbacks);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        getLoaderManager().destroyLoader(LOADER_RECENTS);
+    }
+
+    private OnItemClickListener mItemListener = new OnItemClickListener() {
+        @Override
+        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+            final DocumentStack stack = mAdapter.getItem(position);
+            ((DocumentsActivity) getActivity()).onStackPicked(stack);
+        }
+    };
+
+    public static class RecentsCreateLoader extends UriDerivativeLoader<List<DocumentStack>> {
+        public RecentsCreateLoader(Context context) {
+            super(context, RecentsProvider.buildRecentCreate());
+        }
+
+        @Override
+        public List<DocumentStack> loadInBackground(Uri uri, CancellationSignal signal) {
+            final ArrayList<DocumentStack> result = Lists.newArrayList();
+
+            final ContentResolver resolver = getContext().getContentResolver();
+            final Cursor cursor = resolver.query(
+                    uri, null, null, null, RecentsProvider.COL_TIMESTAMP + " DESC", signal);
+            try {
+                while (cursor != null && cursor.moveToNext()) {
+                    final String rawStack = cursor.getString(
+                            cursor.getColumnIndex(RecentsProvider.COL_PATH));
+                    final DocumentStack stack = DocumentStack.deserialize(resolver, rawStack);
+                    result.add(stack);
+                }
+            } finally {
+                IoUtils.closeQuietly(cursor);
+            }
+
+            return result;
+        }
+    }
+
+    private class DocumentStackAdapter extends BaseAdapter {
+        private List<DocumentStack> mStacks;
+
+        public DocumentStackAdapter() {
+        }
+
+        public void swapStacks(List<DocumentStack> stacks) {
+            mStacks = stacks;
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+
+            if (convertView == null) {
+                final LayoutInflater inflater = LayoutInflater.from(context);
+                convertView = inflater.inflate(R.layout.item_doc_list, parent, false);
+            }
+
+            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final View line2 = convertView.findViewById(R.id.line2);
+
+            final DocumentStack stack = getItem(position);
+            final Root root = RootsCache.findRoot(context, stack.peek());
+            icon.setImageDrawable(root != null ? root.icon : null);
+
+            final StringBuilder builder = new StringBuilder();
+            final int size = stack.size();
+            for (int i = 0; i < size; i++) {
+                builder.append(stack.get(i).displayName);
+                if (i <  size - 1) {
+                    builder.append(" \u232a ");
+                }
+            }
+            title.setText(builder.toString());
+            title.setEllipsize(TruncateAt.MIDDLE);
+
+            line2.setVisibility(View.GONE);
+
+            return convertView;
+        }
+
+        @Override
+        public int getCount() {
+            return mStacks != null ? mStacks.size() : 0;
+        }
+
+        @Override
+        public DocumentStack getItem(int position) {
+            return mStacks.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return getItem(position).hashCode();
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
index dbcb039..5268c1d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
@@ -129,11 +129,11 @@
         switch (sMatcher.match(uri)) {
             case URI_RECENT_OPEN: {
                 return db.query(TABLE_RECENT_OPEN, projection,
-                        buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, null);
+                        buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, sortOrder);
             }
             case URI_RECENT_CREATE: {
                 return db.query(TABLE_RECENT_CREATE, projection,
-                        buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, null);
+                        buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, sortOrder);
             }
             case URI_RESUME: {
                 final String packageName = uri.getPathSegments().get(1);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index 1b56a20..b26db3b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -30,6 +30,7 @@
 import android.util.Log;
 import android.util.Pair;
 
+import com.android.documentsui.model.Document;
 import com.android.documentsui.model.DocumentsProviderInfo;
 import com.android.documentsui.model.DocumentsProviderInfo.Icon;
 import com.android.documentsui.model.Root;
@@ -58,7 +59,7 @@
 
     public static ArrayList<Root> sRootsList = Lists.newArrayList();
 
-    private static Root sRecentOpenRoot;
+    private static Root sRecentsRoot;
 
     /**
      * Gather roots from all known storage providers.
@@ -73,9 +74,9 @@
 
         {
             // Create special root for recents
-            final Root root = Root.buildRecentOpen(context);
+            final Root root = Root.buildRecents(context);
             sRootsList.add(root);
-            sRecentOpenRoot = root;
+            sRecentsRoot = root;
         }
 
         // Query for other storage backends
@@ -125,13 +126,21 @@
     }
 
     @GuardedBy("ActivityThread")
-    public static Root getRecentOpenRoot(Context context) {
-        ensureCache(context);
-        return sRecentOpenRoot;
+    public static Root findRoot(Context context, Document doc) {
+        final String authority = doc.uri.getAuthority();
+        final String rootId = DocumentsContract.getRootId(doc.uri);
+        return findRoot(context, authority, rootId);
     }
 
     @GuardedBy("ActivityThread")
-    public static Collection<Root> getRoots() {
+    public static Root getRecentsRoot(Context context) {
+        ensureCache(context);
+        return sRecentsRoot;
+    }
+
+    @GuardedBy("ActivityThread")
+    public static Collection<Root> getRoots(Context context) {
+        ensureCache(context);
         return sRootsList;
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index 3e645bc..c4e9c15 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -69,7 +69,7 @@
         final View view = inflater.inflate(R.layout.fragment_roots, container, false);
         mList = (ListView) view.findViewById(android.R.id.list);
 
-        mAdapter = new SectionedRootsAdapter(context, RootsCache.getRoots());
+        mAdapter = new SectionedRootsAdapter(context, RootsCache.getRoots(context));
         mList.setAdapter(mAdapter);
         mList.setOnItemClickListener(mItemListener);
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/Document.java b/packages/DocumentsUI/src/com/android/documentsui/model/Document.java
index ed69690..3b82ba8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/Document.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/Document.java
@@ -35,26 +35,22 @@
     public final String displayName;
     public final long lastModified;
     public final int flags;
+    public final String summary;
+    public final long size;
 
-    private Document(Uri uri, String mimeType, String displayName, long lastModified, int flags) {
+    private Document(Uri uri, String mimeType, String displayName, long lastModified, int flags,
+            String summary, long size) {
         this.uri = uri;
         this.mimeType = mimeType;
         this.displayName = displayName;
         this.lastModified = lastModified;
         this.flags = flags;
+        this.summary = summary;
+        this.size = size;
     }
 
     public static Document fromRoot(ContentResolver resolver, Root root) {
-        if (root.isRecents) {
-            final Uri uri = root.uri;
-            final String mimeType = DocumentsContract.MIME_TYPE_DIRECTORY;
-            final String displayName = root.title;
-            final long lastModified = -1;
-            final int flags = 0;
-            return new Document(uri, mimeType, displayName, lastModified, flags);
-        } else {
-            return fromUri(resolver, root.uri);
-        }
+        return fromUri(resolver, root.uri);
     }
 
     public static Document fromDirectoryCursor(Uri parent, Cursor cursor) {
@@ -67,8 +63,10 @@
         final String displayName = getCursorString(cursor, DocumentColumns.DISPLAY_NAME);
         final long lastModified = getCursorLong(cursor, DocumentColumns.LAST_MODIFIED);
         final int flags = getCursorInt(cursor, DocumentColumns.FLAGS);
+        final String summary = getCursorString(cursor, DocumentColumns.SUMMARY);
+        final long size = getCursorLong(cursor, DocumentColumns.SIZE);
 
-        return new Document(uri, mimeType, displayName, lastModified, flags);
+        return new Document(uri, mimeType, displayName, lastModified, flags, summary, size);
     }
 
     public static Document fromRecentOpenCursor(ContentResolver resolver, Cursor cursor) {
@@ -84,8 +82,10 @@
             final String displayName = getCursorString(itemCursor, DocumentColumns.DISPLAY_NAME);
             final int flags = getCursorInt(itemCursor, DocumentColumns.FLAGS)
                     & DocumentsContract.FLAG_SUPPORTS_THUMBNAIL;
+            final String summary = getCursorString(cursor, DocumentColumns.SUMMARY);
+            final long size = getCursorLong(cursor, DocumentColumns.SIZE);
 
-            return new Document(uri, mimeType, displayName, lastModified, flags);
+            return new Document(uri, mimeType, displayName, lastModified, flags, summary, size);
         } finally {
             itemCursor.close();
         }
@@ -101,22 +101,15 @@
             final String displayName = getCursorString(cursor, DocumentColumns.DISPLAY_NAME);
             final long lastModified = getCursorLong(cursor, DocumentColumns.LAST_MODIFIED);
             final int flags = getCursorInt(cursor, DocumentColumns.FLAGS);
+            final String summary = getCursorString(cursor, DocumentColumns.SUMMARY);
+            final long size = getCursorLong(cursor, DocumentColumns.SIZE);
 
-            return new Document(uri, mimeType, displayName, lastModified, flags);
+            return new Document(uri, mimeType, displayName, lastModified, flags, summary, size);
         } finally {
             cursor.close();
         }
     }
 
-    public static Document fromSearch(Uri relatedUri, String query) {
-        final Uri uri = DocumentsContract.buildSearchUri(relatedUri, query);
-        final String mimeType = DocumentsContract.MIME_TYPE_DIRECTORY;
-        final String displayName = query;
-        final long lastModified = System.currentTimeMillis();
-        final int flags = 0;
-        return new Document(uri, mimeType, displayName, lastModified, flags);
-    }
-
     @Override
     public String toString() {
         return "Document{name=" + displayName + ", uri=" + uri + "}";
@@ -134,23 +127,30 @@
         return (flags & DocumentsContract.FLAG_SUPPORTS_THUMBNAIL) != 0;
     }
 
+    public boolean isDirectory() {
+        return DocumentsContract.MIME_TYPE_DIRECTORY.equals(mimeType);
+    }
+
     private static String getCursorString(Cursor cursor, String columnName) {
-        return cursor.getString(cursor.getColumnIndexOrThrow(columnName));
+        final int index = cursor.getColumnIndex(columnName);
+        return (index != -1) ? cursor.getString(index) : null;
     }
 
     private static long getCursorLong(Cursor cursor, String columnName) {
-        return cursor.getLong(cursor.getColumnIndexOrThrow(columnName));
+        final int index = cursor.getColumnIndex(columnName);
+        return (index != -1) ? cursor.getLong(index) : 0;
     }
 
     private static int getCursorInt(Cursor cursor, String columnName) {
-        return cursor.getInt(cursor.getColumnIndexOrThrow(columnName));
+        final int index = cursor.getColumnIndex(columnName);
+        return (index != -1) ? cursor.getInt(index) : 0;
     }
 
     public static class NameComparator implements Comparator<Document> {
         @Override
         public int compare(Document lhs, Document rhs) {
-            final boolean leftDir = DocumentsContract.MIME_TYPE_DIRECTORY.equals(lhs.mimeType);
-            final boolean rightDir = DocumentsContract.MIME_TYPE_DIRECTORY.equals(rhs.mimeType);
+            final boolean leftDir = lhs.isDirectory();
+            final boolean rightDir = rhs.isDirectory();
 
             if (leftDir != rightDir) {
                 return leftDir ? -1 : 1;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
new file mode 100644
index 0000000..dade8a3
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.model;
+
+import static com.android.documentsui.DocumentsActivity.TAG;
+
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.util.Log;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+
+import java.util.LinkedList;
+
+/**
+ * Representation of a stack of {@link Document}, usually the result of a
+ * user-driven traversal.
+ */
+public class DocumentStack extends LinkedList<Document> {
+
+    public static String serialize(DocumentStack stack) {
+        final JSONArray json = new JSONArray();
+        for (int i = 0; i < stack.size(); i++) {
+            json.put(stack.get(i).uri);
+        }
+        return json.toString();
+    }
+
+    public static DocumentStack deserialize(ContentResolver resolver, String raw) {
+        Log.d(TAG, "restoreStack: " + raw);
+
+        final DocumentStack stack = new DocumentStack();
+        try {
+            final JSONArray json = new JSONArray(raw);
+            for (int i = 0; i < json.length(); i++) {
+                final Uri uri = Uri.parse(json.getString(i));
+                final Document doc = Document.fromUri(resolver, uri);
+                stack.add(doc);
+            }
+        } catch (JSONException e) {
+            Log.w(TAG, "Failed to decode stack", e);
+        }
+
+        // TODO: handle roots that have gone missing
+        return stack;
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/Root.java b/packages/DocumentsUI/src/com/android/documentsui/model/Root.java
index 9d816d7..629dbc4 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/Root.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/Root.java
@@ -43,12 +43,12 @@
     public String summary;
     public boolean isRecents;
 
-    public static Root buildRecentOpen(Context context) {
+    public static Root buildRecents(Context context) {
         final PackageManager pm = context.getPackageManager();
         final Root root = new Root();
         root.rootId = null;
         root.rootType = DocumentsContract.ROOT_TYPE_SHORTCUT;
-        root.uri = RecentsProvider.buildRecentOpen();
+        root.uri = null;
         root.icon = context.getResources().getDrawable(R.drawable.ic_dir);
         root.title = context.getString(R.string.root_recent);
         root.summary = null;
@@ -92,6 +92,13 @@
         return root;
     }
 
+    /**
+     * Return string most suited to showing in a directory listing.
+     */
+    public String getDirectoryString() {
+        return (summary != null) ? summary : title;
+    }
+
     public static class RootComparator implements Comparator<Root> {
         @Override
         public int compare(Root lhs, Root rhs) {
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 72d064a..74fd7a8 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -46,8 +46,8 @@
 
         <activity
             android:name=".PrintJobConfigActivity"
-            android:exported="true"
-            android:theme="@android:style/Theme.Holo.Light.Dialog.NoActionBar">
+            android:exported="false"
+            android:theme="@style/PrintJobConfigActivityTheme">
         </activity>
 
         <receiver
diff --git a/packages/PrintSpooler/res/drawable-hdpi/stat_notify_cancelling.png b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_cancelling.png
new file mode 100644
index 0000000..2757db0
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_cancelling.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-hdpi/stat_notify_error.png b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_error.png
new file mode 100644
index 0000000..7846a78
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_error.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-hdpi/stat_notify_print.png b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_print.png
new file mode 100644
index 0000000..aaff3dd
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_print.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/stat_notify_cancelling.png b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_cancelling.png
new file mode 100644
index 0000000..c1b380a
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_cancelling.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/stat_notify_error.png b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_error.png
new file mode 100644
index 0000000..44109eb
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_error.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/stat_notify_print.png b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_print.png
new file mode 100644
index 0000000..a3954b5
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_print.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_cancelling.png b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_cancelling.png
new file mode 100644
index 0000000..fedc00e
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_cancelling.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_error.png b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_error.png
new file mode 100644
index 0000000..c3faa42
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_error.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_print.png b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_print.png
new file mode 100644
index 0000000..6b55a14
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_print.png
Binary files differ
diff --git a/packages/PrintSpooler/res/layout/generating_print_job_dialog.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
similarity index 65%
rename from packages/PrintSpooler/res/layout/generating_print_job_dialog.xml
rename to packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
index 360f8434..e36b8b5 100644
--- a/packages/PrintSpooler/res/layout/generating_print_job_dialog.xml
+++ b/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
@@ -14,11 +14,15 @@
      limitations under the License.
 -->
 
-<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/progress"
-    android:layout_width="fill_parent"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/content_container"
+    android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:layout_margin="16dip"
-    android:layout_gravity="center_horizontal"
-    style="?android:attr/progressBarStyleLarge">
-</ProgressBar>
+    android:layout_gravity="center"
+    android:background="@color/print_job_config_activity_content_background">
+
+    <include
+        layout="@layout/print_job_config_activity_content_editing">
+    </include>
+
+</FrameLayout>
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
similarity index 94%
rename from packages/PrintSpooler/res/layout/print_job_config_activity.xml
rename to packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
index 1a8b0f1..77ef5a2 100644
--- a/packages/PrintSpooler/res/layout/print_job_config_activity.xml
+++ b/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
@@ -15,12 +15,15 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
+    android:id="@+id/content_editing"
+    android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:orientation="vertical">
+    android:orientation="vertical"
+    android:divider="?android:attr/dividerHorizontal"
+    android:showDividers="middle">
 
     <ScrollView
-        android:layout_width="fill_parent"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:scrollbars="vertical">
@@ -262,17 +265,6 @@
                 android:contentDescription="@null">
             </ImageView>
 
-            <ImageView
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_gravity="fill_horizontal"
-                android:layout_row="10"
-                android:layout_column="0"
-                android:layout_columnSpan="2"
-                android:background="?android:attr/listDivider"
-                android:contentDescription="@null">
-            </ImageView>
-
         </GridLayout>
 
     </ScrollView>
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_content_generating.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_content_generating.xml
new file mode 100644
index 0000000..6352afc
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/print_job_config_activity_content_generating.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/content_generating"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:divider="?android:attr/dividerHorizontal"
+    android:showDividers="middle">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        style="?android:attr/buttonBarButtonStyle"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:textAlignment="viewStart"
+        android:text="@string/generating_print_job" >
+    </TextView>
+
+    <ProgressBar
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="32dip"
+        android:layout_gravity="center_horizontal"
+        style="?android:attr/progressBarStyleLarge">
+    </ProgressBar>
+
+    <Button
+        android:id="@+id/cancel_button"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="fill_horizontal"
+        android:text="@string/cancel_button"
+        style="?android:attr/buttonBarButtonStyle">
+    </Button>
+
+</LinearLayout>
diff --git a/packages/PrintSpooler/res/layout/generating_print_job_dialog.xml b/packages/PrintSpooler/res/values/colors.xml
similarity index 61%
copy from packages/PrintSpooler/res/layout/generating_print_job_dialog.xml
copy to packages/PrintSpooler/res/values/colors.xml
index 360f8434..3d8ba223 100644
--- a/packages/PrintSpooler/res/layout/generating_print_job_dialog.xml
+++ b/packages/PrintSpooler/res/values/colors.xml
@@ -5,7 +5,7 @@
      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
+          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,
@@ -14,11 +14,6 @@
      limitations under the License.
 -->
 
-<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/progress"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
-    android:layout_margin="16dip"
-    android:layout_gravity="center_horizontal"
-    style="?android:attr/progressBarStyleLarge">
-</ProgressBar>
+<resources>
+    <color name="print_job_config_activity_content_background">#FFF2F2F2</color>
+</resources>
\ No newline at end of file
diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml
index fbddf43..8391509 100644
--- a/packages/PrintSpooler/res/values/strings.xml
+++ b/packages/PrintSpooler/res/values/strings.xml
@@ -22,6 +22,9 @@
     <!-- Label of the print dialog's print button. [CHAR LIMIT=16] -->
     <string name="print_button">PRINT</string>
 
+    <!-- Label of the print dialog's cancel button. [CHAR LIMIT=16] -->
+    <string name="cancel_button">CANCEL</string>
+
     <!-- Label of the destination widget. [CHAR LIMIT=20] -->
     <string name="label_destination">DESTIINATION</string>
 
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
new file mode 100644
index 0000000..ab16c65
--- /dev/null
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <style name="PrintJobConfigActivityTheme" parent="@android:style/Theme.Holo.Light.NoActionBar">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowSoftInputMode">stateAlwaysHidden|adjustPan</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:backgroundDimEnabled">true</item>
+        <item name="android:colorBackgroundCacheHint">@android:color/transparent</item>
+    </style>
+
+</resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
index 8b49c0e..130320b 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
@@ -81,12 +81,10 @@
 
     private void createPrintingNotificaiton(PrintJobInfo printJob) {
         Notification.Builder builder = new Notification.Builder(mContext)
-                // TODO: Use appropriate icon when assets are ready
-                .setSmallIcon(android.R.drawable.ic_secure)
+                .setSmallIcon(R.drawable.stat_notify_print)
                 .setContentTitle(mContext.getString(R.string.printing_notification_title_template,
                         printJob.getLabel()))
-                // TODO: Use appropriate icon when assets are ready
-                .addAction(android.R.drawable.ic_secure, mContext.getString(R.string.cancel),
+                .addAction(R.drawable.stat_notify_cancelling, mContext.getString(R.string.cancel),
                         createCancelIntent(printJob))
                 .setContentText(printJob.getPrinterId().getPrinterName())
                 .setWhen(System.currentTimeMillis())
@@ -97,12 +95,10 @@
 
     private void createFailedNotificaiton(PrintJobInfo printJob) {
         Notification.Builder builder = new Notification.Builder(mContext)
-                // TODO: Use appropriate icon when assets are ready
-                .setSmallIcon(android.R.drawable.ic_secure)
+                .setSmallIcon(R.drawable.stat_notify_error)
                 .setContentTitle(mContext.getString(R.string.failed_notification_title_template,
                         printJob.getLabel()))
-                // TODO: Use appropriate icon when assets are ready
-                .addAction(android.R.drawable.ic_secure, mContext.getString(R.string.cancel),
+                .addAction(R.drawable.stat_notify_cancelling, mContext.getString(R.string.cancel),
                         createCancelIntent(printJob))
                 // TODO: Use appropriate icon when assets are ready
                 .addAction(android.R.drawable.ic_secure, mContext.getString(R.string.restart),
@@ -161,8 +157,7 @@
             NotificationManager notificationManager = (NotificationManager)
                     context.getSystemService(Context.NOTIFICATION_SERVICE);
             Notification.Builder builder = new Notification.Builder(context)
-                    // TODO: Use appropriate icon when assets are ready
-                    .setSmallIcon(android.R.drawable.ic_secure)
+                    .setSmallIcon(R.drawable.stat_notify_cancelling)
                     .setContentTitle(context.getString(
                             R.string.cancelling_notification_title_template,
                             printJobLabel))
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 00a76b8..824815f 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -17,11 +17,8 @@
 package com.android.printspooler;
 
 import android.app.Activity;
-import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -57,6 +54,7 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.View.MeasureSpec;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.view.WindowManager;
@@ -147,7 +145,7 @@
     @Override
     protected void onCreate(Bundle bundle) {
         super.onCreate(bundle);
-        setContentView(R.layout.print_job_config_activity);
+        setContentView(R.layout.print_job_config_activity_container);
 
         getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
 
@@ -234,10 +232,14 @@
     }
 
     public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
-                && !event.isCanceled()) {
-            if (!mController.isWorking()) {
-                PrintJobConfigActivity.this.finish();
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            if (mEditor.isShwoingGeneratingPrintJobUi()) {
+                return true;
+            }
+            if (event.isTracking() && !event.isCanceled()) {
+                if (!mController.isWorking()) {
+                    PrintJobConfigActivity.this.finish();
+                }
             }
             mEditor.cancel();
             return true;
@@ -249,31 +251,6 @@
         return !mOldPrintAttributes.equals(mCurrPrintAttributes);
     }
 
-    private void showGeneratingPrintJobUi() {
-        getWindow().getDecorView().setVisibility(View.GONE);
-
-        DialogFragment fragment = new DialogFragment() {
-            @Override
-            public Dialog onCreateDialog(Bundle savedInstanceState) {
-                return new AlertDialog.Builder(PrintJobConfigActivity.this)
-                    .setTitle(getString(R.string.generating_print_job))
-                    .setView(PrintJobConfigActivity.this.getLayoutInflater().inflate(
-                            R.layout.generating_print_job_dialog, null))
-                    .setCancelable(false)
-                    .setPositiveButton(getString(R.string.cancel),
-                            new DialogInterface.OnClickListener() {
-                                @Override
-                                public void onClick(DialogInterface dialog, int which) {
-                                    mEditor.cancel();
-                                    PrintJobConfigActivity.this.finish();
-                                }
-                            })
-                    .create();
-            }
-        };
-        fragment.show(getFragmentManager(), getString(R.string.generating_print_job));
-    }
-
     private class PrintController {
         private final AtomicInteger mRequestCounter = new AtomicInteger();
 
@@ -915,6 +892,67 @@
             updateUi();
         }
 
+        public boolean isShwoingGeneratingPrintJobUi() {
+            return (findViewById(R.id.content_generating) != null);
+        }
+
+        private void showGeneratingPrintJobUi() {
+            // Find everything we will shuffle around.
+            final ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
+            final View contentEditing = contentContainer.findViewById(R.id.content_editing);
+            final View contentGenerating = getLayoutInflater().inflate(
+                    R.layout.print_job_config_activity_content_generating,
+                    contentContainer, false);
+
+            // Wire the cancel action.
+            Button cancelButton = (Button) contentGenerating.findViewById(R.id.cancel_button);
+            cancelButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    if (!mController.isWorking()) {
+                        PrintJobConfigActivity.this.finish();
+                    }
+                    mEditor.cancel();
+                }
+            });
+
+            // First animation - fade out the old content.
+            contentEditing.animate().alpha(0.0f).withEndAction(new Runnable() {
+                @Override
+                public void run() {
+                    contentEditing.setVisibility(View.INVISIBLE);
+
+                    // Prepare the new content with correct size and alpha.
+                    contentGenerating.setMinimumWidth(contentContainer.getWidth());
+                    contentGenerating.setAlpha(0.0f);
+
+                    // Compute how to much shrink the container to fit around the new content.
+                    final int widthSpec = MeasureSpec.makeMeasureSpec(
+                            contentContainer.getWidth(), MeasureSpec.AT_MOST);
+                    final int heightSpec = MeasureSpec.makeMeasureSpec(
+                            contentContainer.getHeight(), MeasureSpec.AT_MOST);
+                    contentGenerating.measure(widthSpec, heightSpec);
+                    final float scaleY = (float) contentGenerating.getMeasuredHeight()
+                            / (float) contentContainer.getHeight();
+
+                    // Second animation - resize the container.
+                    contentContainer.animate().scaleY(scaleY).withEndAction(
+                            new Runnable() {
+                        @Override
+                        public void run() {
+                            // Swap the old and the new content.
+                            contentContainer.removeAllViews();
+                            contentContainer.setScaleY(1.0f);
+                            contentContainer.addView(contentGenerating);
+
+                            // Third animation - show the new content.
+                            contentGenerating.animate().alpha(1.0f);
+                        }
+                    });
+                }
+            });
+        }
+
         public void initialize() {
             mEditorState = EDITOR_STATE_INITIALIZED;
             if (mDestinationSpinner.getSelectedItemPosition() != AdapterView.INVALID_POSITION) {
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 9ddf42a..05618bd 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -182,10 +182,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Outoroteer"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotasie gesluit"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Invoermetode"</string>
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Ligging"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Ligging af"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Mediatoestel"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Net noodoproepe"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 6194fd8..6bf1040 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -182,10 +182,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Автоматична ориентация"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Ориентацията е заключена"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Метод на въвеждане"</string>
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Местоположение"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Местоположението е изключено"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Мултимедийно устройство"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"Индикатор за силата на получения сигнал (RSSI)"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Само спешни обаждания"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index ec52ede..2b59228 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -184,10 +184,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Autom. drehen"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Drehung gesperrt"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Eingabemethode"</string>
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Standort"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Standort aus"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Mediengerät"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Nur Notrufe"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 62f6c20..2a0f1f7 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -184,10 +184,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Girar automáticamente"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotación bloqueada"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de introducción"</string>
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Ubicación"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Ubicación desactivada"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositivo multimedia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Solo emergencia"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b095519..5f35ce6 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -182,10 +182,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"چرخش خودکار"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"چرخش قفل شد"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"روش ورودی"</string>
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"مکان"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"مکان خاموش"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"دستگاه رسانه"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"فقط تماس‌های اضطراری"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 5312ccb..498e922 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -182,10 +182,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Auto Putar"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Putaran Dikunci"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Kaedah Input"</string>
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokasi"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokasi Dimatikan"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Peranti media"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Panggilan Kecemasan Sahaja"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 91e7f02..9be0739 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -184,10 +184,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Girar automat."</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotação bloqueada"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de entrada"</string>
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Localização"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localização desativada"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositivo de mídia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Somente chamadas de emergência"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 27f556c..bdfd27d 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -180,10 +180,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Zungusha Otomatiki"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Mzunguko Umefungwa"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mbinu ya uingizaji"</string>
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Eneo"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Eneo Limezimwa"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Kifaa cha midia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Simu za Dharura Pekee"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index f39f8bc..2185b16 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -182,10 +182,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Otomatik Döndür"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Dönme Kilitlendi"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Giriş Yöntemi"</string>
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Konum"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Konum Bilgisi Kapalı"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Medya cihazı"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Yalnızca Acil Çağrılar İçin"</string>
diff --git a/services/java/com/android/internal/app/ProcessStats.java b/services/java/com/android/internal/app/ProcessStats.java
index e916b56..5e9b6a1 100644
--- a/services/java/com/android/internal/app/ProcessStats.java
+++ b/services/java/com/android/internal/app/ProcessStats.java
@@ -17,6 +17,7 @@
 package com.android.internal.app;
 
 import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -38,7 +39,7 @@
 import java.util.Comparator;
 import java.util.Objects;
 
-final public class ProcessStats {
+final public class ProcessStats implements Parcelable {
     static final String TAG = "ProcessStats";
     static final boolean DEBUG = false;
     
@@ -198,6 +199,22 @@
         reset();
     }
 
+    public ProcessStats(Parcel in) {
+        reset();
+        readFromParcel(in);
+    }
+
+    public static final Parcelable.Creator<ProcessStats> CREATOR
+            = new Parcelable.Creator<ProcessStats>() {
+        public ProcessStats createFromParcel(Parcel in) {
+            return new ProcessStats(in);
+        }
+
+        public ProcessStats[] newArray(int size) {
+            return new ProcessStats[size];
+        }
+    };
+
     static private void printScreenLabel(PrintWriter pw, int offset) {
         switch (offset) {
             case ADJ_NOTHING:
@@ -947,7 +964,13 @@
         return table;
     }
 
-    public void writeToParcel(Parcel out) {
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
         long now = SystemClock.uptimeMillis();
         out.writeInt(MAGIC);
         out.writeInt(PARCEL_VERSION);
@@ -2272,6 +2295,7 @@
             if (mDurationsTable == BAD_TABLE) {
                 return false;
             }
+            mDurationsTableSize = mDurationsTable != null ? mDurationsTable.length : 0;
             mStartedCount = in.readInt();
             mBoundCount = in.readInt();
             mExecCount = in.readInt();
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 457539f..5f3f894 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -314,6 +314,8 @@
                     + ", batteryLevel=" + mBatteryProps.batteryLevel
                     + ", batteryTechnology=" + mBatteryProps.batteryTechnology
                     + ", batteryVoltage=" + mBatteryProps.batteryVoltage
+                    + ", batteryCurrentNow=" + mBatteryProps.batteryCurrentNow
+                    + ", batteryChargeCounter=" + mBatteryProps.batteryChargeCounter
                     + ", batteryTemperature=" + mBatteryProps.batteryTemperature
                     + ", mBatteryLevelCritical=" + mBatteryLevelCritical
                     + ", mPlugType=" + mPlugType);
@@ -613,7 +615,16 @@
                 pw.println("  present: " + mBatteryProps.batteryPresent);
                 pw.println("  level: " + mBatteryProps.batteryLevel);
                 pw.println("  scale: " + BATTERY_SCALE);
-                pw.println("  voltage:" + mBatteryProps.batteryVoltage);
+                pw.println("  voltage: " + mBatteryProps.batteryVoltage);
+
+                if (mBatteryProps.batteryCurrentNow != Integer.MIN_VALUE) {
+                    pw.println("  current now: " + mBatteryProps.batteryCurrentNow);
+                }
+
+                if (mBatteryProps.batteryChargeCounter != Integer.MIN_VALUE) {
+                    pw.println("  charge counter: " + mBatteryProps.batteryChargeCounter);
+                }
+
                 pw.println("  temperature: " + mBatteryProps.batteryTemperature);
                 pw.println("  technology: " + mBatteryProps.batteryTechnology);
             } else if (args.length == 3 && "set".equals(args[0])) {
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 467c0b3..dc2b0ae 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1418,7 +1418,8 @@
                             null : lastStack.topRunningNonDelayedActivityLocked(notTop);
                     if (curTop != null && curTop.task != intentActivity.task) {
                         r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
-                        if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) {
+                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
+                                sourceStack.topActivity().task == sourceRecord.task)) {
                             // We really do want to push this one into the
                             // user's face, right now.
                             movedHome = true;
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index ee6f7ec..8b4a5a0 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -19,6 +19,7 @@
 import android.app.AppGlobals;
 import android.content.pm.IPackageManager;
 import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -27,6 +28,7 @@
 import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.SparseArray;
+import com.android.internal.app.IProcessStats;
 import com.android.internal.app.ProcessStats;
 import com.android.internal.os.BackgroundThread;
 
@@ -38,9 +40,10 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.locks.ReentrantLock;
 
-public final class ProcessStatsService {
+public final class ProcessStatsService extends IProcessStats.Stub {
     static final String TAG = "ProcessStatsService";
     static final boolean DEBUG = false;
 
@@ -204,7 +207,7 @@
                 if (commit) {
                     mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
                 }
-                mProcessStats.writeToParcel(mPendingWrite);
+                mProcessStats.writeToParcel(mPendingWrite, 0);
                 mPendingWriteFile = new AtomicFile(mFile.getBaseFile());
                 mPendingWriteCommitted = commit;
             }
@@ -442,6 +445,33 @@
         return finalRes;
     }
 
+    public byte[] getCurrentStats(List<ParcelFileDescriptor> historic) {
+        Parcel current = Parcel.obtain();
+        mWriteLock.lock();
+        try {
+            synchronized (mLock) {
+                mProcessStats.writeToParcel(current, 0);
+            }
+            if (historic != null) {
+                ArrayList<String> files = getCommittedFiles(0, true);
+                if (files != null) {
+                    for (int i=files.size()-1; i>=0; i--) {
+                        try {
+                            ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
+                                    new File(files.get(i)), ParcelFileDescriptor.MODE_READ_ONLY);
+                            historic.add(pfd);
+                        } catch (IOException e) {
+                            Slog.w(TAG, "Failure opening procstat file " + files.get(i), e);
+                        }
+                    }
+                }
+            }
+        } finally {
+            mWriteLock.unlock();
+        }
+        return current.marshall();
+    }
+
     static private void dumpHelp(PrintWriter pw) {
         pw.println("Process stats (procstats) dump options:");
         pw.println("    [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
diff --git a/services/java/com/android/server/firewall/IntentFirewall.java b/services/java/com/android/server/firewall/IntentFirewall.java
index ab4ac04..58a0324 100644
--- a/services/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/java/com/android/server/firewall/IntentFirewall.java
@@ -86,6 +86,7 @@
                 StringFilter.DATA,
                 StringFilter.HOST,
                 StringFilter.MIME_TYPE,
+                StringFilter.SCHEME,
                 StringFilter.PATH,
                 StringFilter.SSP,
 
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index 35b5c85..bb37917 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -26,6 +26,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.RestrictionEntry;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -116,7 +117,7 @@
 
     private static final int MIN_USER_ID = 10;
 
-    private static final int USER_VERSION = 3;
+    private static final int USER_VERSION = 4;
 
     private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
 
@@ -162,6 +163,8 @@
     private boolean mGuestEnabled;
     private int mNextSerialNumber;
     private int mUserVersion = 0;
+    // Temporary cleanup variable, this and associated code should be removed later.
+    private boolean mUnblockAppsTemp;
 
     private static UserManagerService sInstance;
 
@@ -232,12 +235,14 @@
                 sInstance = this;
             }
         }
-
     }
 
     void systemReady() {
-        mUserPackageMonitor.register(ActivityThread.systemMain().getSystemContext(),
+        final Context context = ActivityThread.systemMain().getSystemContext();
+        mUserPackageMonitor.register(context,
                 null, UserHandle.ALL, false);
+        context.registerReceiver(mBootCompletedReceiver,
+                new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
         userForeground(UserHandle.USER_OWNER);
     }
 
@@ -602,12 +607,17 @@
                 int userId = mRestrictionsPinStates.keyAt(i);
                 RestrictionsPinState state = mRestrictionsPinStates.valueAt(i);
                 if (state.salt != 0 && state.pinHash != null) {
-                    removeRestrictionsForUser(userId);
+                    removeRestrictionsForUser(userId, false);
                 }
             }
             userVersion = 3;
         }
 
+        if (userVersion < 4) {
+            mUnblockAppsTemp = true;
+            userVersion = 4;
+        }
+
         if (userVersion < USER_VERSION) {
             Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to "
                     + USER_VERSION);
@@ -1234,10 +1244,10 @@
     public void removeRestrictions() {
         checkManageUsersPermission("Only system can remove restrictions");
         final int userHandle = UserHandle.getCallingUserId();
-        removeRestrictionsForUser(userHandle);
+        removeRestrictionsForUser(userHandle, true);
     }
 
-    private void removeRestrictionsForUser(final int userHandle) {
+    private void removeRestrictionsForUser(final int userHandle, boolean unblockApps) {
         synchronized (mPackagesLock) {
             // Remove all user restrictions
             setUserRestrictions(new Bundle(), userHandle);
@@ -1246,6 +1256,12 @@
             // Remove any app restrictions
             cleanAppRestrictions(userHandle, true);
         }
+        if (unblockApps) {
+            unblockAllAppsForUser(userHandle);
+        }
+    }
+
+    private void unblockAllAppsForUser(final int userHandle) {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -1572,4 +1588,19 @@
             }
         }
     };
+
+    private BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
+        @Override public void onReceive(Context context, Intent intent) {
+            // This code block can be removed after cleanup
+            if (mUnblockAppsTemp) {
+                synchronized (mPackagesLock) {
+                    // Unblock apps due to removal of restrictions feature
+                    for (int i = 0; i < mUsers.size(); i++) {
+                        int userId = mUsers.keyAt(i);
+                        unblockAllAppsForUser(userId);
+                    }
+                }
+            }
+        }
+    };
 }
diff --git a/services/java/com/android/server/wm/DimLayer.java b/services/java/com/android/server/wm/DimLayer.java
index 7839d06..39e664f 100644
--- a/services/java/com/android/server/wm/DimLayer.java
+++ b/services/java/com/android/server/wm/DimLayer.java
@@ -48,9 +48,10 @@
     /** Time in milliseconds to take to transition from mStartAlpha to mTargetAlpha */
     long mDuration;
 
-    DimLayer(WindowManagerService service, int displayId) {
+    DimLayer(WindowManagerService service, DisplayContent displayContent) {
+        mDisplayContent = displayContent;
+        final int displayId = displayContent.getDisplayId();
         if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);
-        mDisplayContent = service.getDisplayContentLocked(displayId);
         SurfaceControl.openTransaction();
         try {
             if (WindowManagerService.DEBUG_SURFACE_TRACE) {
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index 74676ca..2dcdcdd 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -111,14 +111,25 @@
     /** Save allocating when calculating rects */
     Rect mTmpRect = new Rect();
 
+    final WindowManagerService mService;
+
     /**
      * @param display May not be null.
+     * @param service TODO(cmautner):
      */
-    DisplayContent(Display display) {
+    DisplayContent(Display display, WindowManagerService service) {
         mDisplay = display;
         mDisplayId = display.getDisplayId();
         display.getDisplayInfo(mDisplayInfo);
         isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY;
+        mService = service;
+
+        StackBox newBox = new StackBox(service, this, null);
+        mStackBoxes.add(newBox);
+        TaskStack newStack = new TaskStack(service, HOME_STACK_ID, this);
+        newStack.mStackBox = newBox;
+        newBox.mStack = newStack;
+        mHomeStack = newStack;
     }
 
     int getDisplayId() {
@@ -201,22 +212,15 @@
     }
 
     /** Refer to {@link WindowManagerService#createStack(int, int, int, float)} */
-    TaskStack createStack(WindowManagerService service, int stackId, int relativeStackBoxId,
-            int position, float weight) {
+    TaskStack createStack(int stackId, int relativeStackBoxId, int position, float weight) {
         TaskStack newStack = null;
         if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId + " relativeStackBoxId="
                 + relativeStackBoxId + " position=" + position + " weight=" + weight);
-        if (mStackBoxes.isEmpty()) {
-            if (stackId != HOME_STACK_ID) {
-                throw new IllegalArgumentException("createStack: First stackId not "
-                        + HOME_STACK_ID);
+        if (stackId == HOME_STACK_ID) {
+            if (mStackBoxes.size() != 1) {
+                throw new IllegalArgumentException("createStack: HOME_STACK_ID (0) not first.");
             }
-            StackBox newBox = new StackBox(service, this, null);
-            mStackBoxes.add(newBox);
-            newStack = new TaskStack(service, stackId, this);
-            newStack.mStackBox = newBox;
-            newBox.mStack = newStack;
-            mHomeStack = newStack;
+            newStack = mHomeStack;
         } else {
             int stackBoxNdx;
             for (stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
@@ -225,8 +229,8 @@
                         || position == StackBox.TASK_STACK_GOES_UNDER) {
                     // Position indicates a new box is added at top level only.
                     if (box.contains(relativeStackBoxId)) {
-                        StackBox newBox = new StackBox(service, this, null);
-                        newStack = new TaskStack(service, stackId, this);
+                        StackBox newBox = new StackBox(mService, this, null);
+                        newStack = new TaskStack(mService, stackId, this);
                         newStack.mStackBox = newBox;
                         newBox.mStack = newStack;
                         final int offset = position == StackBox.TASK_STACK_GOES_OVER ? 1 : 0;
diff --git a/services/java/com/android/server/wm/TaskStack.java b/services/java/com/android/server/wm/TaskStack.java
index 29156be..7bb6734 100644
--- a/services/java/com/android/server/wm/TaskStack.java
+++ b/services/java/com/android/server/wm/TaskStack.java
@@ -71,8 +71,8 @@
         mStackId = stackId;
         mDisplayContent = displayContent;
         final int displayId = displayContent.getDisplayId();
-        mDimLayer = new DimLayer(service, displayId);
-        mAnimationBackgroundSurface = new DimLayer(service, displayId);
+        mDimLayer = new DimLayer(service, displayContent);
+        mAnimationBackgroundSurface = new DimLayer(service, displayContent);
     }
 
     DisplayContent getDisplayContent() {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 0750e71..2e84d6d 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -733,6 +733,7 @@
 
         mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
 
+        mFxSession = new SurfaceSession();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
         mDisplayManager.registerDisplayListener(this, null);
         Display[] displays = mDisplayManager.getDisplays();
@@ -779,7 +780,6 @@
                 | PowerManager.ON_AFTER_RELEASE, TAG);
         mHoldingScreenWakeLock.setReferenceCounted(false);
 
-        mFxSession = new SurfaceSession();
         mAnimator = new WindowAnimator(this);
 
         initPolicy(UiThread.getHandler());
@@ -4832,8 +4832,8 @@
             final int numDisplays = mDisplayContents.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-                TaskStack stack = displayContent.createStack(this, stackId, relativeStackBoxId,
-                        position, weight);
+                TaskStack stack = displayContent.createStack(stackId, relativeStackBoxId, position,
+                        weight);
                 if (stack != null) {
                     mStackIdToStack.put(stackId, stack);
                     displayContent.moveStack(stack, true);
@@ -10716,7 +10716,7 @@
     }
 
     private DisplayContent newDisplayContentLocked(final Display display) {
-        DisplayContent displayContent = new DisplayContent(display);
+        DisplayContent displayContent = new DisplayContent(display, this);
         final int displayId = display.getDisplayId();
         mDisplayContents.put(displayId, displayContent);
         final Rect rect = new Rect();