Merge "Don't draw onto a hw surface using the software renderer Bug #6485955" into jb-dev
diff --git a/api/16.txt b/api/16.txt
index 18a4b7b..1a694a8 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -485,6 +485,7 @@
     field public static final int focusable = 16842970; // 0x10100da
     field public static final int focusableInTouchMode = 16842971; // 0x10100db
     field public static final int focusedMonthDateColor = 16843587; // 0x1010343
+    field public static final int fontFamily = 16843692; // 0x10103ac
     field public static final int footerDividersEnabled = 16843311; // 0x101022f
     field public static final int foreground = 16843017; // 0x1010109
     field public static final int foregroundGravity = 16843264; // 0x1010200
@@ -5822,6 +5823,7 @@
     field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
     field public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; // 0x4000000
     field public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
+    field public static final int FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS = 8192; // 0x2000
     field public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; // 0x800000
     field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
     field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
diff --git a/api/current.txt b/api/current.txt
index 8402f31..1a694a8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5823,6 +5823,7 @@
     field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
     field public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; // 0x4000000
     field public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
+    field public static final int FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS = 8192; // 0x2000
     field public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; // 0x800000
     field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
     field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index ac55abe..69ee434 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2713,7 +2713,16 @@
                 onCreateNavigateUpTaskStack(b);
                 onPrepareNavigateUpTaskStack(b);
                 b.startActivities();
-                finishAffinity();
+
+                // We can't finishAffinity if we have a result.
+                // Fall back and simply finish the current activity instead.
+                if (mResultCode != RESULT_CANCELED || mResultData != null) {
+                    // Tell the developer what's going on to avoid hair-pulling.
+                    Log.i(TAG, "onNavigateUp only finishing topmost activity to return a result");
+                    finish();
+                } else {
+                    finishAffinity();
+                }
             } else {
                 navigateUpTo(upIntent);
             }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index da09a18..718a917 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -808,13 +808,16 @@
      * always present to the user a list of the things they can do, with a
      * nice title given by the caller such as "Send this photo with:".
      * <p>
+     * If you need to grant URI permissions through a chooser, you must specify
+     * the permissions to be granted on the ACTION_CHOOSER Intent
+     * <em>in addition</em> to the EXTRA_INTENT inside.  This means using
+     * {@link #setClipData} to specify the URIs to be granted as well as
+     * {@link #FLAG_GRANT_READ_URI_PERMISSION} and/or
+     * {@link #FLAG_GRANT_WRITE_URI_PERMISSION} as appropriate.
+     * <p>
      * As a convenience, an Intent of this form can be created with the
      * {@link #createChooser} function.
      * <p>
-     * If the target {@link #EXTRA_INTENT} contains {@link ClipData}, you should
-     * also copy it to this intent along with relevant flags, such as
-     * {@link #FLAG_GRANT_READ_URI_PERMISSION}.
-     * <p>
      * Input: No data should be specified.  get*Extra must have
      * a {@link #EXTRA_INTENT} field containing the Intent being executed,
      * and can optionally have a {@link #EXTRA_TITLE} field containing the
@@ -828,6 +831,14 @@
     /**
      * Convenience function for creating a {@link #ACTION_CHOOSER} Intent.
      *
+     * <p>Builds a new {@link #ACTION_CHOOSER} Intent that wraps the given
+     * target intent, also optionally supplying a title.  If the target
+     * intent has specified {@link #FLAG_GRANT_READ_URI_PERMISSION} or
+     * {@link #FLAG_GRANT_WRITE_URI_PERMISSION}, then these flags will also be
+     * set in the returned chooser intent, with its ClipData set appropriately:
+     * either a direct reflection of {@link #getClipData()} if that is non-null,
+     * or a new ClipData build from {@link #getData()}.
+     *
      * @param target The Intent that the user will be selecting an activity
      * to perform.
      * @param title Optional title that will be displayed in the chooser.
@@ -843,12 +854,26 @@
         }
 
         // Migrate any clip data and flags from target.
-        final ClipData targetClipData = target.getClipData();
-        if (targetClipData != null) {
-            intent.setClipData(targetClipData);
-            intent.addFlags(target.getFlags()
-                    & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION));
+        int permFlags = target.getFlags()
+                & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);
+        if (permFlags != 0) {
+            ClipData targetClipData = target.getClipData();
+            if (targetClipData == null && target.getData() != null) {
+                ClipData.Item item = new ClipData.Item(target.getData());
+                String[] mimeTypes;
+                if (target.getType() != null) {
+                    mimeTypes = new String[] { target.getType() };
+                } else {
+                    mimeTypes = new String[] { };
+                }
+                targetClipData = new ClipData(null, mimeTypes, item);
+            }
+            if (targetClipData != null) {
+                intent.setClipData(targetClipData);
+                intent.addFlags(permFlags);
+            }
         }
+
         return intent;
     }
 
@@ -3078,6 +3103,17 @@
      */
     public static final int FLAG_ACTIVITY_TASK_ON_HOME = 0X00004000;
     /**
+     * If set in an Intent passed to {@link Context#startActivity Context.startActivity()},
+     * upon starting the activity the system will also clear any system dialogs that
+     * are currently shown.  This is intended primarily for any actions that are
+     * associated with buttons in a notification: tapping on the button to launch
+     * the activity needs to also dismiss the notification window (which is one
+     * of the system dialogs); setting this flag on the Intent associated with that
+     * action will ensure that and other system dialogs are dismissed so that the
+     * user arrives in the new activity.
+     */
+    public static final int FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS = 0X00002000;
+    /**
      * If set, when sending a broadcast only registered receivers will be
      * called -- no BroadcastReceiver components will be launched.
      */
diff --git a/core/java/android/preference/MultiSelectListPreference.java b/core/java/android/preference/MultiSelectListPreference.java
index 2e8d551..553ce80 100644
--- a/core/java/android/preference/MultiSelectListPreference.java
+++ b/core/java/android/preference/MultiSelectListPreference.java
@@ -125,8 +125,9 @@
      * @param values The values to set for the key.
      */
     public void setValues(Set<String> values) {
-        mValues = values;
-        
+        mValues.clear();
+        mValues.addAll(values);
+
         persistStringSet(values);
     }
     
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 16f9a18..6dc31dd 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -29,7 +29,6 @@
 import android.util.PoolableManager;
 import android.util.Pools;
 import android.util.SparseLongArray;
-import android.view.ViewGroup.ChildListForAccessibility;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
@@ -623,6 +622,8 @@
 
         private static final int MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE = 50;
 
+        private final ArrayList<View> mTempViewList = new ArrayList<View>();
+
         public void prefetchAccessibilityNodeInfos(View view, int virtualViewId, int prefetchFlags,
                 List<AccessibilityNodeInfo> outInfos) {
             AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
@@ -663,8 +664,6 @@
             while (parent instanceof View
                     && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                 View parentView = (View) parent;
-                final long parentNodeId = AccessibilityNodeInfo.makeNodeId(
-                        parentView.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
                 AccessibilityNodeInfo info = parentView.createAccessibilityNodeInfo();
                 if (info != null) {
                     outInfos.add(info);
@@ -678,19 +677,21 @@
             ViewParent parent = current.getParentForAccessibility();
             if (parent instanceof ViewGroup) {
                 ViewGroup parentGroup = (ViewGroup) parent;
-                ChildListForAccessibility children = ChildListForAccessibility.obtain(parentGroup,
-                        false);
+                ArrayList<View> children = mTempViewList;
+                children.clear();
                 try {
-                    final int childCount = children.getChildCount();
+                    parentGroup.addChildrenForAccessibility(children);
+                    final int childCount = children.size();
                     for (int i = 0; i < childCount; i++) {
                         if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                             return;
                         }
-                        View child = children.getChildAt(i);
+                        View child = children.get(i);
                         if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
                                 &&  isShown(child)) {
                             AccessibilityNodeInfo info = null;
-                            AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
+                            AccessibilityNodeProvider provider =
+                                child.getAccessibilityNodeProvider();
                             if (provider == null) {
                                 info = child.createAccessibilityNodeInfo();
                             } else {
@@ -703,7 +704,7 @@
                         }
                     }
                 } finally {
-                    children.recycle();
+                    children.clear();
                 }
             }
         }
@@ -716,14 +717,16 @@
             ViewGroup rootGroup = (ViewGroup) root;
             HashMap<View, AccessibilityNodeInfo> addedChildren =
                 new HashMap<View, AccessibilityNodeInfo>();
-            ChildListForAccessibility children = ChildListForAccessibility.obtain(rootGroup, false);
+            ArrayList<View> children = mTempViewList;
+            children.clear();
             try {
-                final int childCount = children.getChildCount();
+                root.addChildrenForAccessibility(children);
+                final int childCount = children.size();
                 for (int i = 0; i < childCount; i++) {
                     if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                         return;
                     }
-                    View child = children.getChildAt(i);
+                    View child = children.get(i);
                     if (isShown(child)) {
                         AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
                         if (provider == null) {
@@ -743,7 +746,7 @@
                     }
                 }
             } finally {
-                children.recycle();
+                children.clear();
             }
             if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                 for (Map.Entry<View, AccessibilityNodeInfo> entry : addedChildren.entrySet()) {
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index bd341d0..20b5f17 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -19,6 +19,7 @@
 import android.accessibilityservice.IAccessibilityServiceConnection;
 import android.graphics.Rect;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Message;
 import android.os.Process;
@@ -27,10 +28,14 @@
 import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.SparseArray;
+import android.util.SparseLongArray;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Queue;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -74,6 +79,8 @@
 
     private static final boolean DEBUG = false;
 
+    private static final boolean CHECK_INTEGRITY = true;
+
     private static final long TIMEOUT_INTERACTION_MILLIS = 5000;
 
     private static final Object sStaticLock = new Object();
@@ -491,6 +498,9 @@
                 result = Collections.emptyList();
             }
             clearResultLocked();
+            if (Build.IS_DEBUGGABLE && CHECK_INTEGRITY) {
+                checkFindAccessibilityNodeInfoResultIntegrity(result);
+            }
             return result;
         }
     }
@@ -696,4 +706,56 @@
             sConnectionCache.remove(connectionId);
         }
     }
+
+    /**
+     * Checks whether the infos are a fully connected tree with no duplicates.
+     *
+     * @param infos The result list to check.
+     */
+    private void checkFindAccessibilityNodeInfoResultIntegrity(List<AccessibilityNodeInfo> infos) {
+        if (infos.size() == 0) {
+            return;
+        }
+        // Find the root node.
+        AccessibilityNodeInfo root = infos.get(0);
+        final int infoCount = infos.size();
+        for (int i = 1; i < infoCount; i++) {
+            for (int j = i; j < infoCount; j++) {
+                AccessibilityNodeInfo candidate = infos.get(j);
+                if (root.getParentNodeId() == candidate.getSourceNodeId()) {
+                    root = candidate;
+                    break;
+                }
+            }
+        }
+        if (root == null) {
+            Log.e(LOG_TAG, "No root.");
+        }
+        // Check for duplicates.
+        HashSet<AccessibilityNodeInfo> seen = new HashSet<AccessibilityNodeInfo>();
+        Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
+        fringe.add(root);
+        while (!fringe.isEmpty()) {
+            AccessibilityNodeInfo current = fringe.poll();
+            if (!seen.add(current)) {
+                Log.e(LOG_TAG, "Duplicate node.");
+                return;
+            }
+            SparseLongArray childIds = current.getChildNodeIds();
+            final int childCount = childIds.size();
+            for (int i = 0; i < childCount; i++) {
+                final long childId = childIds.valueAt(i);
+                for (int j = 0; j < infoCount; j++) {
+                    AccessibilityNodeInfo child = infos.get(j);
+                    if (child.getSourceNodeId() == childId) {
+                        fringe.add(child);
+                    }
+                }
+            }
+        }
+        final int disconnectedCount = infos.size() - seen.size();
+        if (disconnectedCount > 0) {
+            Log.e(LOG_TAG, disconnectedCount + " Disconnected nodes.");
+        }
+    }
 }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index 52b7772..14954be 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -244,7 +244,7 @@
     /**
      * We are enforcing the invariant for a single accessibility focus.
      *
-     * @param currentInputFocusId The current input focused node.
+     * @param currentAccessibilityFocusId The current input focused node.
      */
     private void clearSubtreeWithOldAccessibilityFocusLocked(long currentAccessibilityFocusId) {
         final int cacheSize = mCacheImpl.size();
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index b825e1b..515f0c4 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -2490,7 +2490,7 @@
                 info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INCREMENT);
             }
 
-            info.setParent((View) getParent());
+            info.setParent((View) getParentForAccessibility());
             info.setEnabled(NumberPicker.this.isEnabled());
             info.setScrollable(true);
             Rect boundsInParent = mTempRect;
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 25cfb7f..4ec0197 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -185,10 +185,10 @@
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Bruge funktioner, der hurtigt kan dræne batteriet."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Direkte adgang til kalender og begivenheder."</string>
-    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Læs brugerordbog"</string>
-    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Læs ord i brugerordbogen."</string>
-    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Skriv brugerordbog"</string>
-    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Føj ord til brugerordbogen."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Læse brugerordbog"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Læse ord i brugerordbogen."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Skrive brugerordbog"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Føje ord til brugerordbogen."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bogmærker og historik"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkte adgang til bogmærker og browserhistorik."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarm"</string>
@@ -561,7 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Tillader, at appen læser USB-lagerets indhold, herunder billeder og mediefiler."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Tillader, at appen læser SD-kortets indhold, som kan omfatte billeder og mediefiler."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ændre eller slette indhold på USB-lager"</string>
-    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"skift eller slet indholdet på dit SD-kort"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"ændre eller slette indholdet på dit SD-kort"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Lader appen skrive til USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tillader, at appen kan skrive til SD-kortet."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Rediger/slet internt medielagringsindhold"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 3d51570..4ca2b86 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1091,7 +1091,7 @@
     <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Bei der Verwendung Ihres USB-Speichers als USB-Massenspeicher ist ein Problem aufgetreten."</string>
     <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Bei der Verwendung Ihrer SD-Karte als USB-Massenspeicher ist ein Problem aufgetreten."</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB-Verbindung"</string>
-    <string name="usb_storage_notification_message" msgid="939822783828183763">"Zum Kopieren von Dateien auf den/von dem Computer berühren"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Zum Kopieren von Dateien berühren"</string>
     <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB-Speicher deaktivieren"</string>
     <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Zum Deaktivieren des USB-Speichers berühren"</string>
     <string name="usb_storage_stop_title" msgid="660129851708775853">"USB-Speicher in Verwendung"</string>
@@ -1114,7 +1114,7 @@
     <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Alle Daten auf Ihrer Karte gehen verloren."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging"</string>
-    <string name="adb_active_notification_message" msgid="1016654627626476142">"Zum Deaktivieren von USB-Debugging tippen"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Zum Deaktivieren von USB-Debugging berühren"</string>
     <string name="select_input_method" msgid="4653387336791222978">"Eingabemethode wählen"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Eingabemethoden einrichten"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Physische Tastatur"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 616b9be..5bca912 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -185,12 +185,9 @@
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Menggunakan fitur yang dapat menguras baterai dengan cepat."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Akses langsung ke kalender dan acara."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Membaca Kamus Pengguna"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Membaca kata dalam kamus pengguna."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Menulis Kamus Pengguna"</string>
     <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Menambahkan kata ke kamus pengguna."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmark dan Riwayat"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Akses langsung ke bookmark dan riwayat browser."</string>
@@ -564,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Izinkan aplikasi membaca konten penyimpanan USB, yang mungkin mencakup foto dan media."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Izinkan aplikasi membaca konten kartu SD, yang mungkin mencakup foto dan media."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ubah/hapus konten pympanan USB"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"mengubah atau menghapus konten kartu SD Anda"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Mengizinkan apl menulis ke penyimpanan USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Memungkinkan apl menulis ke kartu SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubah/hapus konten penyimpanan media internal"</string>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index f7b0cd0..f01562c 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -244,8 +244,13 @@
         mContext = this;
         mChannel = mWifiManager.initialize(mContext, mContext.getMainLooper(), null);
 
-        initializeNetworkStates();
+        if (mWifiManager.isWifiApEnabled()) {
+            // if soft AP is enabled, disable it
+            mWifiManager.setWifiApEnabled(null, false);
+            log("Disable soft ap");
+        }
 
+        initializeNetworkStates();
         log("Clear Wifi before we start the test.");
         removeConfiguredNetworksAndDisableWifi();
         mWifiRegexs = mCM.getTetherableWifiRegexs();
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 7e136be..60595fb 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -103,7 +103,7 @@
             assertTrue(mAct.mWifiManager.setWifiApEnabled(config, true));
             // Wait for wifi ap state to be ENABLED
             assertTrue(mAct.waitForWifiAPState(WifiManager.WIFI_AP_STATE_ENABLED,
-                    ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                    2 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
             // Wait for wifi tethering result
             assertEquals(ConnectivityManagerTestActivity.SUCCESS,
                     mAct.waitForTetherStateChange(2*ConnectivityManagerTestActivity.SHORT_TIMEOUT));
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 649ec3e..39e2cf2 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -83,6 +83,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
+
         mAct = getActivity();
         mRunner = (ConnectivityManagerStressTestRunner) getInstrumentation();
         mReconnectIterations = mRunner.mReconnectIterations;
@@ -97,11 +98,6 @@
         mOutputWriter = new BufferedWriter(new FileWriter(new File(
                 Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
         mAct.turnScreenOn();
-        if (mAct.mWifiManager.isWifiApEnabled()) {
-            // if soft AP is enabled, disable it
-            assertTrue(mAct.mWifiManager.setWifiApEnabled(null, false));
-            Log.v(TAG, "disable soft ap");
-        }
         if (!mAct.mWifiManager.isWifiEnabled()) {
             log("Enable wi-fi before stress tests.");
             if (!mAct.enableWifi()) {
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index b33a097..847681b 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -528,20 +528,22 @@
 which indicates the current device orientation.</p>
       </td>
     </tr>
-    <tr id="DockQualifier">
-      <td>Dock mode</td>
+    <tr id="UiModeQualifier">
+      <td>UI mode</td>
       <td>
         <code>car</code><br/>
-        <code>desk</code>
+        <code>desk</code><br/>
+        <code>television</code>
       </td>
       <td>
         <ul class="nolist">
-          <li>{@code car}: Device is in a car dock</li>
-          <li>{@code desk}: Device is in a desk dock</li>
+          <li>{@code car}: Device is displaying in a car dock</li>
+          <li>{@code desk}: Device is displaying in a desk dock</li>
+          <li>{@code television}: Device is displaying on a television</li>
         </ul>
-        <p><em>Added in API level 8.</em></p>
+        <p><em>Added in API level 8, television added in API 13.</em></p>
         <p>This can change during the life of your application if the user places the device in a
-dock. You can enable or disable this mode using {@link
+dock. You can enable or disable some of these modes using {@link
 android.app.UiModeManager}. See <a href="runtime-changes.html">Handling Runtime Changes</a> for
 information about how this affects your application during runtime.</p>
       </td>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 46adfd7..aae070a 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -26,7 +26,7 @@
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"सूची से निकालें"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"एप्‍लिकेशन जानकारी"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"कोई हाल ही के एप्लिकेशन नहीं"</string>
-    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के एप्लिकेशन ख़ारिज करें"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के एप्लिकेशन खारिज करें"</string>
   <plurals name="status_bar_accessibility_recent_apps">
     <item quantity="one" msgid="5854176083865845541">"1 हाल ही का एप्लिकेशन"</item>
     <item quantity="other" msgid="1040784359794890744">"%d हाल ही के एप्लिकेशन"</item>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index a117252..a69fc23 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -141,8 +141,7 @@
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktifkan tirai layar"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info aplikasi"</string>
     <string name="notifications_off_title" msgid="8936620513608443224">"Pemberitahuan mati"</string>
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
+    <string name="notifications_off_text" msgid="2529001315769385273">"Ketuk di sini untuk menyalakan pemberitahuan lagi."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Layar akan diputar secara otomatis."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Layar dikunci dalam orientasi lanskap."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Layar dikunci dalam orientasi potret."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 3277fb6..7a7d08f 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -38,7 +38,7 @@
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея разряжена."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Осталось <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Зарядка через порт USB не поддерживается."\n"Используйте только зарядное устройство из комплекта поставки."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Расход заряда батареи"</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Подробнее"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Настройки"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим полета"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 5026d6d..1fa3b21 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -141,7 +141,7 @@
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Vklop ohranjevalnika zaslona"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Podatki o aplikaciji"</string>
     <string name="notifications_off_title" msgid="8936620513608443224">"Obvestila so izklopljena"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Dotaknite se tukaj, da spet vklopite obvestila."</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Dotaknite se tukaj, da ponovno vklopite obvestila."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon se bo samodejno zasukal."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Zaslon je zaklenjen v ležeči usmerjenosti."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Zaslon je zaklenjen v pokončni usmerjenosti."</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 8293d99..4f3e787 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -142,7 +142,7 @@
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Ulwazi lohlelo lokusebenza"</string>
     <string name="notifications_off_title" msgid="8936620513608443224">"Izaziso zivaliwe"</string>
     <string name="notifications_off_text" msgid="2529001315769385273">"Thepha lapha ukuvula futhi izaziso."</string>
-    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzanzakalela."</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzenzakalela."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Isikrini sikhiyelwe ngomumo we-landscape."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Isikrini sikhiyelwe ngomumo we-portrait."</string>
 </resources>
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 54ef724..76016f4 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3510,31 +3510,36 @@
 
     public void closeSystemDialogs(String reason) {
         enforceNotIsolatedCaller("closeSystemDialogs");
+
+        final int uid = Binder.getCallingUid();
+        final long origId = Binder.clearCallingIdentity();
+        synchronized (this) {
+            closeSystemDialogsLocked(uid, reason);
+        }
+        Binder.restoreCallingIdentity(origId);
+    }
+
+    void closeSystemDialogsLocked(int callingUid, String reason) {
         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
         if (reason != null) {
             intent.putExtra("reason", reason);
         }
+        mWindowManager.closeSystemDialogs(reason);
         
-        final int uid = Binder.getCallingUid();
-        final long origId = Binder.clearCallingIdentity();
-        synchronized (this) {
-            mWindowManager.closeSystemDialogs(reason);
-            
-            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
-                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
-                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
-                    r.stack.finishActivityLocked(r, i,
-                            Activity.RESULT_CANCELED, null, "close-sys");
-                }
+        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
+            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
+            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
+                r.stack.finishActivityLocked(r, i,
+                        Activity.RESULT_CANCELED, null, "close-sys");
             }
-            
-            broadcastIntentLocked(null, null, intent, null,
-                    null, 0, null, null, null, false, false, -1, uid, 0 /* TODO: Verify */);
         }
-        Binder.restoreCallingIdentity(origId);
+        
+        broadcastIntentLocked(null, null, intent, null,
+                null, 0, null, null, null, false, false, -1,
+                callingUid, 0 /* TODO: Verify */);
     }
-    
+
     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
             throws RemoteException {
         enforceNotIsolatedCaller("getProcessMemoryInfo");
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index e6f4d918..5b15e50 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -52,6 +52,7 @@
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserId;
@@ -2532,6 +2533,10 @@
             mDismissKeyguardOnNextActivity = false;
             mService.mWindowManager.dismissKeyguard();
         }
+        if (err >= ActivityManager.START_SUCCESS &&
+                (launchFlags&Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS) != 0) {
+            mService.closeSystemDialogsLocked(Process.myUid(), "launch");
+        }
         return err;
     }
   
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index cba92f3..5516dea 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -935,6 +935,59 @@
         mDtDy = mWin.mGlobalScale;
     }
 
+    void updateSurfaceWindowCrop(final boolean recoveringMemory) {
+        final WindowState w = mWin;
+
+        // Need to recompute a new system decor rect each time.
+        if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
+            // Currently can't do this cropping for scaled windows.  We'll
+            // just keep the crop rect the same as the source surface.
+            w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
+        } else if (w.mLayer >= mService.mSystemDecorLayer) {
+            // Above the decor layer is easy, just use the entire window.
+            w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
+                    w.mCompatFrame.height());
+        } else {
+            final Rect decorRect = mService.mSystemDecorRect;
+            // Compute the offset of the window in relation to the decor rect.
+            final int offX = w.mXOffset + w.mFrame.left;
+            final int offY = w.mYOffset + w.mFrame.top;
+            // Initialize the decor rect to the entire frame.
+            w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
+            // Intersect with the decor rect, offsetted by window position.
+            w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
+                    decorRect.right-offX, decorRect.bottom-offY);
+            // If size compatibility is being applied to the window, the
+            // surface is scaled relative to the screen.  Also apply this
+            // scaling to the crop rect.  We aren't using the standard rect
+            // scale function because we want to round things to make the crop
+            // always round to a larger rect to ensure we don't crop too
+            // much and hide part of the window that should be seen.
+            if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
+                final float scale = w.mInvGlobalScale;
+                w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
+                w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
+                w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
+                w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
+            }
+        }
+
+        if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
+            w.mLastSystemDecorRect.set(w.mSystemDecorRect);
+            try {
+                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "CROP " + w.mSystemDecorRect.toShortString(), null);
+                mSurface.setWindowCrop(w.mSystemDecorRect);
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Error setting crop surface of " + w
+                        + " crop=" + w.mSystemDecorRect.toShortString(), e);
+                if (!recoveringMemory) {
+                    mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
+                }
+            }
+        }
+    }
+
     void setSurfaceBoundaries(final boolean recoveringMemory) {
         final WindowState w = mWin;
         int width, height;
@@ -1003,54 +1056,7 @@
             }
         }
 
-        // Need to recompute a new system decor rect each time.
-        if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
-            // Currently can't do this cropping for scaled windows.  We'll
-            // just keep the crop rect the same as the source surface.
-            w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
-        } else if (w.mLayer >= mService.mSystemDecorLayer) {
-            // Above the decor layer is easy, just use the entire window.
-            w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
-                    w.mCompatFrame.height());
-        } else {
-            final Rect decorRect = mService.mSystemDecorRect;
-            // Compute the offset of the window in relation to the decor rect.
-            final int offX = w.mXOffset + w.mFrame.left;
-            final int offY = w.mYOffset + w.mFrame.top;
-            // Initialize the decor rect to the entire frame.
-            w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
-            // Intersect with the decor rect, offsetted by window position.
-            w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
-                    decorRect.right-offX, decorRect.bottom-offY);
-            // If size compatibility is being applied to the window, the
-            // surface is scaled relative to the screen.  Also apply this
-            // scaling to the crop rect.  We aren't using the standard rect
-            // scale function because we want to round things to make the crop
-            // always round to a larger rect to ensure we don't crop too
-            // much and hide part of the window that should be seen.
-            if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
-                final float scale = w.mInvGlobalScale;
-                w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
-                w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
-                w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
-                w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
-            }
-        }
-
-        if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
-            w.mLastSystemDecorRect.set(w.mSystemDecorRect);
-            try {
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "CROP " + w.mSystemDecorRect.toShortString(), null);
-                mSurface.setWindowCrop(w.mSystemDecorRect);
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Error setting crop surface of " + w
-                        + " crop=" + w.mSystemDecorRect.toShortString(), e);
-                if (!recoveringMemory) {
-                    mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
-                }
-            }
-        }
+        updateSurfaceWindowCrop(recoveringMemory);
     }
 
     public void prepareSurfaceLocked(final boolean recoveringMemory) {
@@ -1181,17 +1187,31 @@
     }
 
     void setWallpaperOffset(int left, int top) {
+        mSurfaceX = left;
+        mSurfaceY = top;
+        if (mAnimating) {
+            // If this window (or its app token) is animating, then the position
+            // of the surface will be re-computed on the next animation frame.
+            // We can't poke it directly here because it depends on whatever
+            // transformation is being applied by the animation.
+            return;
+        }
+        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                ">>> OPEN TRANSACTION setWallpaperOffset");
         Surface.openTransaction();
         try {
-            mSurfaceX = left;
-            mSurfaceY = top;
-            mSurface.setPosition(left, top);
-            mSurface.setWindowCrop(null);
+            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
+                    "POS " + left + ", " + top, null);
+            mSurface.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
+            updateSurfaceWindowCrop(false);
         } catch (RuntimeException e) {
             Slog.w(TAG, "Error positioning surface of " + mWin
                     + " pos=(" + left + "," + top + ")", e);
+        } finally {
+            Surface.closeTransaction();
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                    "<<< CLOSE TRANSACTION setWallpaperOffset");
         }
-        Surface.closeTransaction();
     }
 
     // This must be called while inside a transaction.