Merge "update overview page for rs api docs to open iframe links in parent" into ics-mr1
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f5add25..d569e20 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -113,7 +113,10 @@
      * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
      * that you take care of task management as described in the
      * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
-     * Stack</a> document.
+     * Stack</a> document.  In particular, make sure to read the notification section
+     * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#HandlingNotifications">Handling
+     * Notifications</a> for the correct ways to launch an application from a
+     * notification.
      */
     public PendingIntent contentIntent;
 
@@ -765,7 +768,9 @@
          * Supply a {@link PendingIntent} to send when the notification is clicked.
          * If you do not supply an intent, you can now add PendingIntents to individual
          * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
-         * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
+         * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.  Be sure to
+         * read {@link Notification#contentIntent Notification.contentIntent} for
+         * how to correctly use this.
          */
         public Builder setContentIntent(PendingIntent intent) {
             mContentIntent = intent;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 924cb53..8ab468d 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -298,6 +298,11 @@
         boolean isDisplayedLw();
 
         /**
+         * Is this window considered to be gone for purposes of layout?
+         */
+        boolean isGoneForLayoutLw();
+
+        /**
          * Returns true if this window has been shown on screen at some time in 
          * the past.  Must be called with the window manager lock held.
          * 
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 5118351..95c9b49 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -283,6 +283,7 @@
     const int N = zipFile.getNumEntries();
 
     char fileName[PATH_MAX];
+    bool hasPrimaryAbi = false;
 
     for (int i = 0; i < N; i++) {
         const ZipEntryRO entry = zipFile.findEntryByIndex(i);
@@ -318,11 +319,22 @@
         if (cpuAbi.size() == cpuAbiRegionSize
                 && *(cpuAbiOffset + cpuAbi.size()) == '/'
                 && !strncmp(cpuAbiOffset, cpuAbi.c_str(), cpuAbiRegionSize)) {
-            LOGV("Using ABI %s\n", cpuAbi.c_str());
+            LOGV("Using primary ABI %s\n", cpuAbi.c_str());
+            hasPrimaryAbi = true;
         } else if (cpuAbi2.size() == cpuAbiRegionSize
                 && *(cpuAbiOffset + cpuAbi2.size()) == '/'
                 && !strncmp(cpuAbiOffset, cpuAbi2.c_str(), cpuAbiRegionSize)) {
-            LOGV("Using ABI %s\n", cpuAbi2.c_str());
+
+            /*
+             * If this library matches both the primary and secondary ABIs,
+             * only use the primary ABI.
+             */
+            if (hasPrimaryAbi) {
+                LOGV("Already saw primary ABI, skipping secondary ABI %s\n", cpuAbi2.c_str());
+                continue;
+            } else {
+                LOGV("Using secondary ABI %s\n", cpuAbi2.c_str());
+            }
         } else {
             LOGV("abi didn't match anything: %s (end at %zd)\n", cpuAbiOffset, cpuAbiRegionSize);
             continue;
diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf
index 6d32fba..40ecd14 100644
--- a/data/fonts/Roboto-Bold.ttf
+++ b/data/fonts/Roboto-Bold.ttf
Binary files differ
diff --git a/data/fonts/Roboto-BoldItalic.ttf b/data/fonts/Roboto-BoldItalic.ttf
index fc2da4c..d9067c54 100644
--- a/data/fonts/Roboto-BoldItalic.ttf
+++ b/data/fonts/Roboto-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf
index ce2e072..88e4a5b 100644
--- a/data/fonts/Roboto-Italic.ttf
+++ b/data/fonts/Roboto-Italic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf
index 465dfc1..f592adf 100644
--- a/data/fonts/Roboto-Regular.ttf
+++ b/data/fonts/Roboto-Regular.ttf
Binary files differ
diff --git a/docs/html/guide/appendix/market-filters.jd b/docs/html/guide/appendix/market-filters.jd
index 6610f5f..07b9370 100644
--- a/docs/html/guide/appendix/market-filters.jd
+++ b/docs/html/guide/appendix/market-filters.jd
@@ -398,8 +398,8 @@
       the device's SIM (for GSM devices), not the current roaming carrier.</p></li></ul>
 </td> </tr> <tr>
   <td valign="top">Native Platform</td> <td valign="top"><p>An application that includes native
-    libraries that target a specific platform (ARM EABI v7, for example) will only be
-    visible on devices that support that platform. For details about the NDK and using
+    libraries that target a specific platform (ARM EABI v7 or x86, for example) are
+    visible only on devices that support that platform. For details about the NDK and using
     native libraries, see <a href="{@docRoot}sdk/ndk/index.html#overview">What is the
       Android NDK?</a></p> </tr> <tr>
         <td valign="top">Copy-Protected Applications</td> <td valign="top"><p>To
diff --git a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
index 31ad466..5faa7ec 100644
--- a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
@@ -40,7 +40,7 @@
       <li><a href=#reusing_tip>Handle case where no activity matches</a></li>
       <li><a href=#activity_launching_tip>Consider how to launch your activities</a></li>
       <li><a href=#activities_added_to_task_tip>Allow activities to add to current task</a></li>
-      <li><a href=#notifications_get_back_tip>Notifications should let user easily get back</li>
+      <li><a href=#notifications_get_back_tip>Notifications and App Widgets should provide consistent back behavior</li>
       <li><a href=#use_notification_tip>Use the notification system</a></li>
       <li><a href=#taking_over_back_key>Don't take over BACK key unless you absolutely need to</a></li>
     </ol>
@@ -1063,110 +1063,23 @@
 </p>
 
     
-<h3 id="notifications_get_back_tip">Notifications should let the user easily get back to the previous activity</h3>
+<h3 id="notifications_get_back_tip">Notifications and App Widgets should provide consistent back behavior</h3>
 <p>
-  Applications that are in the background or not running can have
-  services that send out notifications to the user letting them know about
-  events of interest. Two examples are Calendar, which can send out notifications of
-  upcoming events, and Email, which can send out notifications when new
-  messages arrive. One of the user interface guidelines is that when the
-  user is in activity A, gets a notification for activity B and
-  picks that notification, when they press the BACK key, they should
-  go back to activity A.&nbsp;
+  Notifications and app widgets are two common ways that a user can launch
+  your app through something besides its main icon in Launcher.  You must
+  take care when implementing these so that the user has a consistent experience
+  with the back button, not causing surprises in where they return to or the
+  state the application ends up in.
 </p>
 
 <p>
-  The following scenario shows how the activity stack should work
-  when the user responds to a notification.
-</p>
-
-<ol>
-  <li>
-    User is creating a new event in Calendar. They realize they
-    need to copy part of an email message into this event
-  </li>
-  <li>
-    The user chooses Home &gt; Gmail
-  </li>
-  <li>
-    While in Gmail, they receive a notification from Calendar for an upcoming meeting
-  </li>
-  <li>
-    So they choose that notification, which takes them to a
-    dedicated Calendar activity that displays brief details of the
-    upcoming meeting
-  </li>
-  <li>
-    The user chooses this short notice to view further details
-  </li>
-  <li>
-    When done viewing the event, the user presses the BACK
-    key. They should be taken to Gmail, which is where they were
-    when they took the notification
-  </li>
-</ol>
-
-<p>
-This behavior doesn't necessarily happen by default.
-</p>
-
-<p>
-Notifications generally happen primarily in one of two ways:
-</p>
-
-  <ul>
-    <li>
-      <b>The chosen activity is dedicated for notification only</b> -
-      For example, when the user receives a
-      Calendar notification, choosing that
-      notification starts a special activity that displays a list
-      of upcoming calendar events &mdash; this view is available only
-      from the notification, not through the Calendar's own user
-      interface. After viewing this upcoming event, to ensure that
-      the user pressing the BACK key will return to the activity
-      the user was in when they picked the notification, you would
-      make sure this dedicated activity does not have the same
-      task affinity as the Calendar or any other activity. (You do
-      this by setting task affinity to the empty string, which
-      means it has no affinity to anything.) The explanation for
-      this follows.
-
-      <p>
-      Because of the way tasks work, if the taskAffinity of the
-      dedicated activity is kept as its default, then pressing the
-      BACK key (in step 6, above) would go to Calendar, rather
-      than Gmail. The reason is that, by default, all activities
-      in a given application have the same task
-      affinity. Therefore, the task affinity of the dedicated
-      activity matches the Calendar task, which is already running
-      in step 1. This means in step 4, choosing the notification
-      brings the existing Calendar event (in step 1) forward and
-      starts the dedicated activity on top of it.  This is not
-      what you want to have happen. Setting the dedicated
-      activity's taskAffinity to empty string fixes this.
-      </p>
-    </li>
-
-    <li>
-      <b>The chosen activity is not dedicated, but always comes to
-      the foreground in its initial state</b> - For example, in
-      response to a notification, when the Gmail application comes
-      to the foreground, it always presents the list of conversations.
-      You can ensure this happens by setting a "clear top" flag in the
-      intent that the notification triggers.  This ensures that when the
-      activity is launched, it displays its initial activity, preventing
-      Gmail from coming to the foreground in whatever state the user last
-      happened to be viewing it. (To do this, you put {@link
-      android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP
-      FLAG_ACTIVITY_CLEAR_TOP} in the intent you pass to startActivity()). 
-    </li>
-  </ul>
-
-<p>
-  There are other ways to handle notifications, such as bringing the
-  activity to the foreground, set to display specific data, such as
-  displaying the text message thread for the person who just sent a
-  new text message.
+  The
+  <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#HandlingNotifications">Handling
+  Notifications</a> section of the developer guide's
+  <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
+  documentation provides an overview of how to write code to correctly handle
+  notification.  This dicussion applies equally to handling interactions with
+  app widgets.
 </p>
 
 <p>
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 3a176e6..380791a 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -231,6 +231,9 @@
     </ul>
     <p>You can append more than one <em>{@code &lt;qualifier&gt;}</em>. Separate each
 one with a dash.</p>
+    <p class="caution"><strong>Caution:</strong> When appending multiple qualifiers, you must
+place them in the same order in which they are listed in table 2. If the qualifiers are ordered
+wrong, the resources are ignored.</p>
   </li>
   <li>Save the respective alternative resources in this new directory. The resource files must be
 named exactly the same as the default resource files.</li>
@@ -254,20 +257,14 @@
 the same. This way, the resource ID that you use to reference the {@code icon.png} or {@code
 background.png} image is always the same, but Android selects the
 version of each resource that best matches the current device, by comparing the device
-configuration information with the qualifiers in the alternative resource directory name.</p>
+configuration information with the qualifiers in the resource directory name.</p>
 
 <p>Android supports several configuration qualifiers and you can
 add multiple qualifiers to one directory name, by separating each qualifier with a dash. Table 2
 lists the valid configuration qualifiers, in order of precedence&mdash;if you use multiple
-qualifiers for one resource directory, they must be added to the directory name in the order they
+qualifiers for a resource directory, you must add them to the directory name in the order they
 are listed in the table.</p>
 
-<p class="note"><strong>Note:</strong> Some configuration qualifiers were added after Android 1.0,
-so not
-all versions of Android support all the qualifiers listed in table 2. New qualifiers
-indicate the version in which they were added. To avoid any issues, always include a set of default
-resources for resources that your application uses. For more information, see the section about <a
-href="#Compatibility">Providing the Best Device Compatibility with Resources</a>.</p>
 
 <p class="table-caption" id="table2"><strong>Table 2.</strong> Configuration qualifier
 names.</p>
@@ -752,6 +749,17 @@
 </table>
 
 
+<p class="note"><strong>Note:</strong> Some configuration qualifiers have been added since Android
+1.0, so not all versions of Android support all the qualifiers. Using a new qualifier implicitly
+adds the platform version qualifier so that older devices are sure to ignore it. For example, using
+a <code>w600dp</code> qualifier will automatically include the <code>v13</code> qualifier, because
+the available-width qualifier was new in API level 13. To avoid any issues, always include a set of
+default resources (a set of resources with <em>no qualifiers</em>). For more information, see the
+section about <a href="#Compatibility">Providing the Best Device Compatibility with
+Resources</a>.</p>
+
+
+
 <h3 id="QualifierRules">Qualifier name rules</h3>
 
 <p>Here are some rules about using configuration qualifier names:</p>
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index 71aa2fe..33b0fec 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -16,6 +16,7 @@
     <h2>In this document</h2>
     <ol>
       <li><a href="#Basics">The Basics</a></li>
+      <li><a href="#HandlingNotifications">Responding to Notifications</a></li>
       <li><a href="#ManageYourNotifications">Managing your Notifications</a></li>
       <li><a href="#CreateANotification">Creating a Notification</a>
         <ol>
@@ -137,6 +138,138 @@
 </ol>
 
 
+<h2 id="HandlingNotifications">Responding to Notifications</h2>
+
+<p>A central part of the user's experience with a notification revolves around
+how it interacts with the application's UI flow.  You must implement
+this correctly to provide a consistent user experience within your app.</p>
+
+<p>Two typical examples of notifications are provided by Calendar, which can send out
+notifications of upcoming events, and Email, which can send out notifications
+when new messages arrive.  These represent the two recommended patterns for handling
+notifications: either launching into an activity that is separate from the
+main application, or launching an entirely new instance of the application
+showing the appropriate point for the notification.</p>
+
+<p>The following scenario shows how the activity stack should work
+in these two typical notification flows, first handling a Calendar notification:
+</p>
+
+<ol>
+  <li>User is creating a new event in Calendar. They realize they
+    need to copy part of an email message into this event.
+  </li>
+  <li>
+    The user chooses Home &gt; Email.
+  </li>
+  <li>
+    While in Email, they receive a notification from Calendar for an upcoming
+    meeting.
+  </li>
+  <li>
+    So they choose that notification, which takes them to a
+    dedicated Calendar activity that displays brief details of the
+    upcoming meeting.
+  </li>
+  <li>
+    The user has seen enough to know they have a meeting coming up,
+    so they press the BACK button.  They are now returned to Email, which
+    is where they were when they took the notification.
+  </li>
+</ol>
+
+<p>Handling an Email notification:</p>
+
+<ol>
+  <li>
+    The user is currently in Email composing a message, and needs to
+    check a date in their calendar.
+  </li>
+  <li>
+    The user chooses Home &gt; Calendar.
+  </li>
+  <li>
+    While in Calendar, they receive a notification from Email about a new
+    message.
+  </li>
+  <li>
+    They select the notification, which brings them to Email with the message
+    details displayed.  This has replaced what they were previously doing
+    (writing an e-mail), but that message is still saved in their drafts.
+  </li>
+  <li>
+    The user presses BACK once to go to the message list (the typical flow in the
+    Email app), and press BACK again to return to Calendar as they left it.
+  </li>
+</ol>
+
+<p>In an Email style of notification, the UI launched by the notification
+shows the main application in a state representing that notification.
+For example, when the Email application comes to the foreground from its
+notification, it displays either the conversion list or a specific
+conversation depending on whether there are multiple or only one new
+email.  To achieve this, we want to completely replace whatever current
+state the application is in with a new activity stack representing the
+new notification state.</p>
+
+<p>The following code illustrates how to show this kind of notification.  Of
+most interest is the <code>makeMessageIntentStack()</code> method, which constructs
+an array of intents representing the app's new activity stack for this state.
+(If you are using fragments, you may need to initialize your fragment and
+app state so that pressing BACK will switch the UI back to its parent state.)
+The core of this is the {@link android.content.Intent#makeRestartActivityTask
+Intent.makeRestartActivityTask()} method, which constructs the root activity
+of the stack with the appropriate flags, such as
+{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK Intent.FLAG_ACTIVITY_CLEAR_TASK}.</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
+  app_notification}
+
+<p>In a Calendar style of notification, the UI launched by the notification
+is a dedicated activity that is not part of the normal application flow.
+For example, when the user receives a Calendar notification, choosing that
+notification starts a special activity that displays a list
+of upcoming calendar events &mdash; this view is available only
+from the notification, not through the Calendar's normal user
+interface.</p>
+
+<p>The code for posting this type of notification is very straight-forward; it
+is like the above, but the {@link android.app.PendingIntent} is for just a single
+activity, our dedicated notification activity.</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
+  interstitial_notification}
+
+<p>This is not enough, however.  Normally Android considers all activities within
+an application to be part of that application's UI flow, so simply launching the
+activity like this can cause it to be mixed with your normal application back stack
+in undesired ways.  To make it behave correctly, in the manifest declaration
+for the activity the attributes 
+<code>android:launchMode="singleInstance"</code> and
+<code>android:excludeFromRecents="true"</code>
+must be set.  The full activity declaration for this sample is:</p>
+
+{@sample development/samples/ApiDemos/AndroidManifest.xml interstitial_affinity}
+
+<p>Because of the use of <code>singleInstance</code>, you must be careful about launching
+any other activities from this one.  These activities will be launched
+in their own task, and care must be taken to make sure this interacts
+well with the current state of your application's task.  This is essentially
+the same as switching to the main application as described for the Email style
+notification shown before.  Given the <code>makeMessageIntentStack()</code>
+method previously shown, handling a click here would look something like this:</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessageInterstitial.java
+  app_launch}
+
+<p>If you don't want to use the <code>singleInstance</code> launch mode for
+this activity, an alternative approach is to use <code>android:taskAffinity=""</code>.
+This tells Android that the activity should not be treated as part of the
+main application flow, so it will not get mixed together with that.  All of the
+other issues discussed here do still apply, though this would allow you to start
+additional activities that are part of this notification task instead of switching
+to and replacing the main application task.</p>
+
 <h2 id="ManageYourNotifications">Managing your Notifications</h2>
 
 <p>The {@link android.app.NotificationManager} is a system service that manages all
diff --git a/docs/html/guide/topics/usb/adk.jd b/docs/html/guide/topics/usb/adk.jd
index 99c5f92..4d5fbfa 100644
--- a/docs/html/guide/topics/usb/adk.jd
+++ b/docs/html/guide/topics/usb/adk.jd
@@ -281,16 +281,17 @@
       <p>On Mac:</p>
 
       <ol type="a">
-        <li>Right-click on the Arduino application in Finder and select <strong>Show Package
-        Contents</strong>.</li>
+        <li>Create, if it does not already exist, an <code>Arduino</code>
+        directory inside your user account's <code>Documents</code> directory, and within
+        that, a <code>libraries</code> directory.</li>
 
         <li>Copy the <code>firmware/arduino_libs/AndroidAccessory</code> and
-        <code>firmware/arduino_libs/USB_Host_Shield</code> directories (the complete directories,
-        not just the files within) to the <code>Contents/Resources/Java/libraries</code> directory
-        inside the Arduino application.</li>
+        <code>firmware/arduino_libs/USB_Host_Shield</code> directories (the
+        complete directories, not just the files within) to your
+        <code>Documents/Arduino/libraries/</code> directory.</li>
 
-        <li>Create a <code>CapSense</code> directory in the
-        <code>Contents/Resources/Java/libraries</code> directory.</li>
+        <li>Create a <code>CapSense</code> directory in your
+        <code>Documents/Arduino/libraries/</code> directory.</li>
 
         <li>Copy <code>CapSense.cpp</code> and <code>CapSense.h</code> from the unzipped CapSense
         download to the <code>CapSense</code> directory.</li>
diff --git a/docs/html/sdk/android-4.0.3.jd b/docs/html/sdk/android-4.0.3.jd
index c17a422..1fca8df 100644
--- a/docs/html/sdk/android-4.0.3.jd
+++ b/docs/html/sdk/android-4.0.3.jd
@@ -58,12 +58,34 @@
 environment, refer to the "Installed Packages" listing in the Android SDK
 Manager.</p>
 
+<p class="caution"><strong>Important:</strong> To download the new Android
+4.0.x system components from the Android SDK Manager, you must first update the
+SDK tools to revision 14 or later and restart the Android SDK Manager. If you do not,
+the Android 4.0.x system components will not be available for download.</p>
 
 <div class="toggle-content opened" style="padding-left:1em;">
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png"
 class="toggle-content-img" alt="" />
+    Android {@sdkPlatformVersion}, Revision 2</a> <em>(January 2012)</em>
+  </a></p>
+
+  <div class="toggle-content-toggleme" style="padding-left:2em;">
+
+<dl>
+<dt>Maintenance release. SDK Tools r14 or higher is required.
+</dt>
+</dl>
+
+  </div>
+</div>
+
+<div class="toggle-content closed" style="padding-left:1em;">
+
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png"
+class="toggle-content-img" alt="" />
     Android {@sdkPlatformVersion}, Revision 1</a> <em>(December 2011)</em>
   </a></p>
 
@@ -71,17 +93,12 @@
 
 <dl>
 <dt>Initial release. SDK Tools r14 or higher is required.
-  <p class="caution"><strong>Important:</strong> To download the new Android
-  4.0.x system components from the Android SDK Manager, you must first update the
-  SDK tools to revision 14 or later and restart the Android SDK Manager. If you do not,
-  the Android 4.0.x system components will not be available for download.</p>
 </dt>
 </dl>
 
   </div>
 </div>
 
-
 <h2 id="api">API Overview</h2>
 
 <p>The sections below provide a technical overview of new APIs in Android 4.0.3.</p>
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 0b223c1..eeade05 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2336,7 +2336,7 @@
         if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
                 + win.isVisibleOrBehindKeyguardLw());
         if (mTopFullscreenOpaqueWindowState == null &&
-                win.isVisibleOrBehindKeyguardLw()) {
+                win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
             if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
                 mForceStatusBar = true;
             }
@@ -2391,7 +2391,7 @@
                 // case though.
                 if (topIsFullscreen) {
                     if (mStatusBarCanHide) {
-                        if (DEBUG_LAYOUT) Log.v(TAG, "Hiding status bar");
+                        if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
                         if (mStatusBar.hideLw(true)) {
                             changes |= FINISH_LAYOUT_REDO_LAYOUT;
 
@@ -2407,7 +2407,7 @@
                         Log.v(TAG, "Preventing status bar from hiding by policy");
                     }
                 } else {
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar: top is not fullscreen");
+                    if (DEBUG_LAYOUT) Log.v(TAG, "** SHOWING status bar: top is not fullscreen");
                     if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
                 }
             }
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 4ef8837..4d5e0a6 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -195,7 +195,7 @@
     boolean mProvisioned;
     boolean mAutoRestore;
     PowerManager.WakeLock mWakelock;
-    HandlerThread mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND);
+    HandlerThread mHandlerThread;
     BackupHandler mBackupHandler;
     PendingIntent mRunBackupIntent, mRunInitIntent;
     BroadcastReceiver mRunBackupReceiver, mRunInitReceiver;
@@ -1310,14 +1310,10 @@
             }
             if (added) {
                 synchronized (mBackupParticipants) {
-                    for (String pkgName : pkgList) {
-                        if (replacing) {
-                            // The package was just upgraded
-                            updatePackageParticipantsLocked(pkgName);
-                        } else {
-                            // The package was just added
-                            addPackageParticipantsLocked(pkgName);
-                        }
+                    if (replacing) {
+                        updatePackageParticipantsLocked(pkgList);
+                    } else {
+                        addPackageParticipantsLocked(pkgList);
                     }
                 }
             } else {
@@ -1325,9 +1321,7 @@
                     // The package is being updated.  We'll receive a PACKAGE_ADDED shortly.
                 } else {
                     synchronized (mBackupParticipants) {
-                        for (String pkgName : pkgList) {
-                            removePackageParticipantsLocked(pkgName);
-                        }
+                        removePackageParticipantsLocked(pkgList);
                     }
                 }
             }
@@ -1349,26 +1343,26 @@
         }
     };
 
-    // Add the backup agents in the given package to our set of known backup participants.
-    // If 'packageName' is null, adds all backup agents in the whole system.
-    void addPackageParticipantsLocked(String packageName) {
+    // Add the backup agents in the given packages to our set of known backup participants.
+    // If 'packageNames' is null, adds all backup agents in the whole system.
+    void addPackageParticipantsLocked(String[] packageNames) {
         // Look for apps that define the android:backupAgent attribute
-        if (DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: " + packageName);
         List<PackageInfo> targetApps = allAgentPackages();
-        addPackageParticipantsLockedInner(packageName, targetApps);
+        if (packageNames != null) {
+            if (DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: #" + packageNames.length);
+            for (String packageName : packageNames) {
+                addPackageParticipantsLockedInner(packageName, targetApps);
+            }
+        } else {
+            if (DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: all");
+            addPackageParticipantsLockedInner(null, targetApps);
+        }
     }
 
     private void addPackageParticipantsLockedInner(String packageName,
             List<PackageInfo> targetPkgs) {
         if (MORE_DEBUG) {
-            Slog.v(TAG, "Adding " + targetPkgs.size() + " backup participants:");
-            for (PackageInfo p : targetPkgs) {
-                Slog.v(TAG, "    " + p + " agent=" + p.applicationInfo.backupAgentName
-                        + " uid=" + p.applicationInfo.uid
-                        + " killAfterRestore="
-                        + (((p.applicationInfo.flags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0) ? "true" : "false")
-                        );
-            }
+            Slog.v(TAG, "Examining " + packageName + " for backup agent");
         }
 
         for (PackageInfo pkg : targetPkgs) {
@@ -1380,6 +1374,7 @@
                     mBackupParticipants.put(uid, set);
                 }
                 set.add(pkg.applicationInfo);
+                if (MORE_DEBUG) Slog.v(TAG, "Agent found; added");
 
                 // If we've never seen this app before, schedule a backup for it
                 if (!mEverStoredApps.contains(pkg.packageName)) {
@@ -1391,34 +1386,32 @@
         }
     }
 
-    // Remove the given package's entry from our known active set.  If
-    // 'packageName' is null, *all* participating apps will be removed.
-    void removePackageParticipantsLocked(String packageName) {
-        if (DEBUG) Slog.v(TAG, "removePackageParticipantsLocked: " + packageName);
-        List<String> allApps = new ArrayList<String>();
-        if (packageName != null) {
-            allApps.add(packageName);
-        } else {
-            // all apps with agents
-            List<PackageInfo> knownPackages = allAgentPackages();
-            for (PackageInfo pkg : knownPackages) {
-                allApps.add(pkg.packageName);
-            }
+    // Remove the given packages' entries from our known active set.
+    void removePackageParticipantsLocked(String[] packageNames) {
+        if (packageNames == null) {
+            Slog.w(TAG, "removePackageParticipants with null list");
+            return;
         }
-        removePackageParticipantsLockedInner(packageName, allApps);
+
+        if (DEBUG) Slog.v(TAG, "removePackageParticipantsLocked: #" + packageNames.length);
+        List<PackageInfo> knownPackages = allAgentPackages();
+        for (String pkg : packageNames) {
+            removePackageParticipantsLockedInner(pkg, knownPackages);
+        }
     }
 
     private void removePackageParticipantsLockedInner(String packageName,
-            List<String> allPackageNames) {
+            List<PackageInfo> allPackages) {
         if (MORE_DEBUG) {
             Slog.v(TAG, "removePackageParticipantsLockedInner (" + packageName
-                    + ") removing " + allPackageNames.size() + " entries");
-            for (String p : allPackageNames) {
-                Slog.v(TAG, "    - " + p);
+                    + ") removing from " + allPackages.size() + " entries");
+            for (PackageInfo p : allPackages) {
+                Slog.v(TAG, "    - " + p.packageName);
             }
         }
-        for (String pkg : allPackageNames) {
-            if (packageName == null || pkg.equals(packageName)) {
+        for (PackageInfo pkg : allPackages) {
+            if (packageName == null || pkg.packageName.equals(packageName)) {
+                /*
                 int uid = -1;
                 try {
                     PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
@@ -1427,22 +1420,28 @@
                     // we don't know this package name, so just skip it for now
                     continue;
                 }
+                */
+                final int uid = pkg.applicationInfo.uid;
+                if (MORE_DEBUG) Slog.i(TAG, "   found pkg " + packageName + " uid=" + uid);
 
                 HashSet<ApplicationInfo> set = mBackupParticipants.get(uid);
                 if (set != null) {
                     // Find the existing entry with the same package name, and remove it.
                     // We can't just remove(app) because the instances are different.
                     for (ApplicationInfo entry: set) {
+                        if (MORE_DEBUG) Slog.i(TAG, "      checking against " + entry.packageName);
                         if (entry.packageName.equals(pkg)) {
                             if (MORE_DEBUG) Slog.v(TAG, "  removing participant " + pkg);
                             set.remove(entry);
-                            removeEverBackedUp(pkg);
+                            removeEverBackedUp(pkg.packageName);
                             break;
                         }
                     }
                     if (set.size() == 0) {
                         mBackupParticipants.delete(uid);
                     }
+                } else {
+                    if (MORE_DEBUG) Slog.i(TAG, "   ... not found in uid mapping");
                 }
             }
         }
@@ -1477,21 +1476,20 @@
 
     // Reset the given package's known backup participants.  Unlike add/remove, the update
     // action cannot be passed a null package name.
-    void updatePackageParticipantsLocked(String packageName) {
-        if (packageName == null) {
-            Slog.e(TAG, "updatePackageParticipants called with null package name");
+    void updatePackageParticipantsLocked(String[] packageNames) {
+        if (packageNames == null) {
+            Slog.e(TAG, "updatePackageParticipants called with null package list");
             return;
         }
-        if (DEBUG) Slog.v(TAG, "updatePackageParticipantsLocked: " + packageName);
+        if (DEBUG) Slog.v(TAG, "updatePackageParticipantsLocked: #" + packageNames.length);
 
-        // brute force but small code size
-        List<PackageInfo> allApps = allAgentPackages();
-        List<String> allAppNames = new ArrayList<String>();
-        for (PackageInfo pkg : allApps) {
-            allAppNames.add(pkg.packageName);
+        if (packageNames.length > 0) {
+            List<PackageInfo> allApps = allAgentPackages();
+            for (String packageName : packageNames) {
+                removePackageParticipantsLockedInner(packageName, allApps);
+                addPackageParticipantsLockedInner(packageName, allApps);
+            }
         }
-        removePackageParticipantsLockedInner(packageName, allAppNames);
-        addPackageParticipantsLockedInner(packageName, allApps);
     }
 
     // Called from the backup task: record that the given app has been successfully
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index f5c2de9..47a7e16 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -7391,8 +7391,11 @@
         final int N = mWindows.size();
         int i;
 
-        if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
-                + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
+        if (DEBUG_LAYOUT) {
+            Slog.v(TAG, "-------------------------------------");
+            Slog.v(TAG, "performLayout: needed="
+                    + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
+        }
         
         mPolicy.beginLayoutLw(dw, dh, mRotation);
 
@@ -7409,19 +7412,20 @@
             // Don't do layout of a window if it is not visible, or
             // soon won't be visible, to avoid wasting time and funky
             // changes while a window is animating away.
-            final AppWindowToken atoken = win.mAppToken;
-            final boolean gone = win.mViewVisibility == View.GONE
-                    || !win.mRelayoutCalled
-                    || (atoken == null && win.mRootToken.hidden)
-                    || (atoken != null && atoken.hiddenRequested)
-                    || win.mAttachedHidden
-                    || win.mExiting || win.mDestroying;
+            final boolean gone = win.isGoneForLayoutLw();
 
             if (DEBUG_LAYOUT && !win.mLayoutAttached) {
-                Slog.v(TAG, "First pass " + win
+                Slog.v(TAG, "1ST PASS " + win
                         + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
                         + " mLayoutAttached=" + win.mLayoutAttached);
-                if (gone) Slog.v(TAG, "  (mViewVisibility="
+                final AppWindowToken atoken = win.mAppToken;
+                if (gone) Slog.v(TAG, "  GONE: mViewVisibility="
+                        + win.mViewVisibility + " mRelayoutCalled="
+                        + win.mRelayoutCalled + " hidden="
+                        + win.mRootToken.hidden + " hiddenRequested="
+                        + (atoken != null && atoken.hiddenRequested)
+                        + " mAttachedHidden=" + win.mAttachedHidden);
+                else Slog.v(TAG, "  VIS: mViewVisibility="
                         + win.mViewVisibility + " mRelayoutCalled="
                         + win.mRelayoutCalled + " hidden="
                         + win.mRootToken.hidden + " hiddenRequested="
@@ -7443,7 +7447,7 @@
                     win.prelayout();
                     mPolicy.layoutWindowLw(win, win.mAttrs, null);
                     win.mLayoutSeq = seq;
-                    if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame="
                             + win.mFrame + " mContainingFrame="
                             + win.mContainingFrame + " mDisplayFrame="
                             + win.mDisplayFrame);
@@ -7461,7 +7465,7 @@
             WindowState win = mWindows.get(i);
 
             if (win.mLayoutAttached) {
-                if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
+                if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
                         + " mHaveFrame=" + win.mHaveFrame
                         + " mViewVisibility=" + win.mViewVisibility
                         + " mRelayoutCalled=" + win.mRelayoutCalled);
@@ -7479,7 +7483,7 @@
                     win.prelayout();
                     mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
                     win.mLayoutSeq = seq;
-                    if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame="
                             + win.mFrame + " mContainingFrame="
                             + win.mContainingFrame + " mDisplayFrame="
                             + win.mDisplayFrame);
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 75bda41..794515b 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -1444,6 +1444,16 @@
                     || mAnimating);
     }
 
+    public boolean isGoneForLayoutLw() {
+        final AppWindowToken atoken = mAppToken;
+        return mViewVisibility == View.GONE
+                || !mRelayoutCalled
+                || (atoken == null && mRootToken.hidden)
+                || (atoken != null && (atoken.hiddenRequested || atoken.hidden))
+                || mAttachedHidden
+                || mExiting || mDestroying;
+    }
+
     /**
      * Returns true if the window has a surface that it has drawn a
      * complete UI in to.
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 2c4fdef..04ba42d 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -1029,8 +1029,10 @@
                     didDisable = true;
                 }
             }
-            if (didDisable && enabledCount == 0) {
-                onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
+            if (didDisable) {
+                if (enabledCount == 0) {
+                    onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
+                }
 
                 // send the disconnect msg manually, since the normal route wont send
                 // it (it's not enabled)