A few odds and ends.

- Add documentation on "television" UI mode.
- Tweak new documentation and implementation around propagating
  URI grants through choosers.
- Add new activity launch flag for closing system dialogs.

Change-Id: I978c05f0dc3d16e1c55d43631828b9efa6335b19
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/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/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/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;
     }