Merge "Secure windows, secure surface views and secure displays." into jb-mr1-dev
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 1e6398f..387f33d 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -141,54 +141,39 @@
     return 0;
 }
 
-int fix_uid(const char *pkgname, uid_t uid, uid_t userId)
+int fix_uid(const char *pkgname, uid_t uid, gid_t gid)
 {
     char pkgdir[PKG_PATH_MAX];
     struct stat s;
     int rc = 0;
 
-    if (uid < AID_SYSTEM) {
-        ALOGE("invalid uid: %d\n", uid);
+    if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
+        ALOGE("invalid uid/gid: %d %d\n", uid, gid);
         return -1;
     }
 
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) {
+    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
         ALOGE("cannot create package path\n");
         return -1;
     }
 
     if (stat(pkgdir, &s) < 0) return -1;
 
-    if (((s.st_uid != 0) && (s.st_uid != AID_INSTALL))
-            || ((s.st_gid != 0) && (s.st_gid != AID_INSTALL))) {
-        ALOGE("fixing uid of pkg not owned by install or root: %s %lu %lu\n", pkgdir, s.st_uid,
-                s.st_gid);
-        return -1;
-    }
-
-    if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) {
-        ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(pkgdir);
+    if (s.st_uid != 0 || s.st_gid != 0) {
+        ALOGE("fixing uid of non-root pkg: %s %lu %lu\n", pkgdir, s.st_uid, s.st_gid);
         return -1;
     }
 
     if (chmod(pkgdir, 0751) < 0) {
         ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
         unlink(pkgdir);
-        return -1;
+        return -errno;
     }
-    if (chown(pkgdir, uid, uid) < 0) {
+    if (chown(pkgdir, uid, gid) < 0) {
         ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
         unlink(pkgdir);
-        return -1;
+        return -errno;
     }
-#ifdef HAVE_SELINUX
-    if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
-        ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(pkgdir);
-        return -1;
-    }
-#endif
 
     return 0;
 }
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 8cbf5b1..26bde19 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -1,5 +1,17 @@
 /*
- * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package android.bluetooth;
diff --git a/core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl b/core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl
index 163e4e2..d5e64f6 100644
--- a/core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl
@@ -1,5 +1,17 @@
 /*
- * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package android.bluetooth;
diff --git a/core/java/android/bluetooth/IBluetoothHealth.aidl b/core/java/android/bluetooth/IBluetoothHealth.aidl
index e741da4..a84a42c 100644
--- a/core/java/android/bluetooth/IBluetoothHealth.aidl
+++ b/core/java/android/bluetooth/IBluetoothHealth.aidl
@@ -1,5 +1,17 @@
 /*
- * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package android.bluetooth;
diff --git a/core/java/android/bluetooth/IBluetoothInputDevice.aidl b/core/java/android/bluetooth/IBluetoothInputDevice.aidl
index 23e6d50..1ebb9ca 100755
--- a/core/java/android/bluetooth/IBluetoothInputDevice.aidl
+++ b/core/java/android/bluetooth/IBluetoothInputDevice.aidl
@@ -1,6 +1,19 @@
 /*
- * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
+
 package android.bluetooth;
 
 import android.bluetooth.BluetoothDevice;
diff --git a/core/java/android/bluetooth/IBluetoothManager.aidl b/core/java/android/bluetooth/IBluetoothManager.aidl
index de8fe91..ed8777c 100755
--- a/core/java/android/bluetooth/IBluetoothManager.aidl
+++ b/core/java/android/bluetooth/IBluetoothManager.aidl
@@ -1,5 +1,17 @@
 /*
- * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package android.bluetooth;
diff --git a/core/java/android/bluetooth/IBluetoothManagerCallback.aidl b/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
index 3e795ea..9551086 100644
--- a/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
@@ -1,5 +1,17 @@
 /*
- * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package android.bluetooth;
diff --git a/core/java/android/bluetooth/IBluetoothPan.aidl b/core/java/android/bluetooth/IBluetoothPan.aidl
index b91bd7d..5a32347 100644
--- a/core/java/android/bluetooth/IBluetoothPan.aidl
+++ b/core/java/android/bluetooth/IBluetoothPan.aidl
@@ -1,6 +1,19 @@
 /*
- * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
+
 package android.bluetooth;
 
 import android.bluetooth.BluetoothDevice;
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index 14ab5d5..9c21b3a 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -23,8 +23,6 @@
     <a class="close" onclick="$('#player-wrapper').hide()">close video</a>
   </div>
 </div>
-
-
 <div class="wrap">
    <!-- Slideshow -->
    <div class="slideshow-container slideshow-develop col-16">
@@ -32,6 +30,45 @@
        <a href="" class="slideshow-next">Next</a>
        <div class="frame">
            <ul>
+              <li class="item carousel-home">
+                 <div class="col-8">
+                   <img
+src="http://4.bp.blogspot.com/-lfjzgG5Dqrk/UHMThRtpRwI/AAAAAAAABpk/h4d3nsmkgPM/s400/mint.png"
+class="play no-shadow no-transform" />
+                 </div>
+                <div class="content-right col-6">
+                  <h2>Building Great Apps for Tablets</h2>
+                  <p>Tablets are a growing part of the Android installed base and they offer new opportunities for user engagement and monetization. If you are targeting tablets, check out the <strong>Tablet App Quality Checklist</strong> for tips and techniques on how to deliver a great app experience for tablet users.  </p>
+                  <p><a
+href="/distribute/googleplay/quality/tablet.html" class="button">Read
+more</a></p>
+                </div>            
+              </li>
+               <li class="item carousel-home">
+                   <div class="col-8">
+                     <img
+src="http://1.bp.blogspot.com/-6K1kfNOdek8/T72bXvtTSQI/AAAAAAAABmw/kYzmJt0_328/s1600/google-play-subscriptions.png" class="play"></div>
+                   <div class="content-right col-6">
+                   <h2>In-app Subscriptions with Trials</h2>
+                   <p>You can now set up a <strong>free trial period</strong> for any Google Play in-app subscription, making it easy for users try your subscriber content before automatically converting to a full subscription. Free trials give you a new way to bring users into your products and engage them effectively. </p>
+                   <p><a class="button"
+href="http://dirkbd.mtv:8809/guide/google/play/billing/billing_subscriptions.html#trials">Read
+more</a></p>
+                   </div>                
+                </li>
+               <li class="item carousel-home">
+                   <div class="col-8">
+                     <img
+src="http://2.bp.blogspot.com/-MgN5DnoO5XU/UHYGYzTcAOI/AAAAAAAABs4/jTS7sKkfBcM/s1600/pubsites.png" class="play"></div>
+                   <div class="content-right col-6">
+                   <p class="title-intro">From the blog:</p>
+                   <h2>New Google Play Developer Console</h2>
+                   <p>All developers can now try the <strong>new Google Play Developer Console</strong>. With a streamlined publishing flow, new language options, and new user ratings statistics, you’ll have better tools for delivering great Android apps that delight users.</p>
+                  <p><a
+href="http://android-developers.blogspot.com/2012/10/new-google-play-developer-console.html" class="button">Read
+more</a></p>
+                   </div>                
+                </li>
                <li class="item carousel-home">
                  <div class="col-8">
                    <img
@@ -42,60 +79,14 @@
                   <p class="title-intro">From the blog:</p>
                   <h2>Getting Your App Ready for Jelly Bean and Nexus 7</h2>
                   <p>For many people, their first taste of Jelly Bean will be on the beautiful 
-                    Nexus 7. While most applications will run just fine on Nexus 7, who wants 
-                    their app to be just fine? Here are some tips for optimizing your application 
+                    <strong>Nexus 7 tablet</strong>. Most applications will run just fine on Nexus 7, but who wants 
+                    their app to be just fine? Here are some tips for optimizing your app 
                     to make the most of this device.</p>
                   <p><a
 href="http://android-developers.blogspot.com/2012/07/getting-your-app-ready-for-jelly-bean.html" class="button">Read
 more</a></p>
                 </div>            
               </li>
-               <li class="item carousel-home">
-                 <div class="col-8">
-                   <img
-src="http://1.bp.blogspot.com/-6qyjPxTuzv0/T6lde-Oq_fI/AAAAAAAABXc/zle7OFEGP44/s400/fddns%2Bcopy.png"
-class="play no-shadow no-transform" />
-                 </div>
-                <div class="content-right col-6">
-                  <p class="title-intro">From the blog:</p>
-                  <h2>Using DialogFragments</h2>
-                  <p>In this post, I'll show how to use DialogFragments with the <a
-href="http://developer.android.com/reference/android/support/v4/app/DialogFragment.html">v4 support
-library</a> (for backward compatibility on pre-Honeycomb devices) to show a simple edit dialog and
-return a result to the calling Activity using an interface.</p>
-                  <p><a
-href="http://android-developers.blogspot.com/2012/05/using-dialogfragments.html" class="button">Read
-more</a></p>
-                </div>            
-              </li>
-               <li class="item carousel-home">
-                   <div class="col-8">
-                     <img
-src="http://1.bp.blogspot.com/-6K1kfNOdek8/T72bXvtTSQI/AAAAAAAABmw/kYzmJt0_328/s1600/google-play-subscriptions.png" class="play"></div>
-                   <div class="content-right col-6">
-                   <p class="title-intro">From the blog:</p>
-                   <h2>In-app Subscriptions in Google Play</h2>
-                   <p>Starting today, developers can use In-app Billing to sell monthly or annual
-subscriptions from inside of their apps. All subscriptions are auto-renewing, for every app and game
-and every type of subscription product.</p>
-                   <p><a class="button"
-href="http://android-developers.blogspot.com/2012/05/in-app-subscriptions-in-google-play.html">Read
-more</a></p>
-                   </div>                
-                </li>
-               <li class="item carousel-home">
-                   <div class="col-8">
-                     <img
-src="{@docRoot}images/home/developers_live.png" class="play"></div>
-                   <div class="content-right col-6">
-                   <h2>Learn what great apps are made of</h2>
-                   <p>Every week we host a live broadcast in which we review a collection of apps and games
-                     nominated by the creators. It's no-holds-barred and we tell you exactly what is flawed or
-                     fantastic in each app and how to make improvements.</p>
-                   <p><a href="" class="button" onclick="$('ul#DevelopersLive li:first
-a').click();return false;">Watch the latest review</a></p>
-                   </div>                
-                </li>
            </ul>
        </div>
    </div>
@@ -111,53 +102,47 @@
 		<div class="feed-container">
 			<div class="feed-frame">
                                 <!-- DEVELOPER NEWS -->
-				<ul>
-					<li><a href="http://android-developers.blogspot.com/2012/06/android-sdk-tools-revision-20.html">
-                                          <div class="feed-image" style="background:url('http://1.bp.blogspot.com/-Kp1qE5du6l8/T-xurIjfPgI/AAAAAAAABAM/kuWQwPgi0rw/s640/newactivity+(1).png') no-repeat 0 0">
-                                          </div>
-                                          <h4>Android SDK Tools, Revision 20</h4>
-                                          <p>Along with the preview of the Android 4.1 (Jelly Bean) platform, we launched Android SDK Tools R20 and ADT 20.0.0. Here are a few things...</p>
-					</a></li>
-					<li><a href="http://android-developers.blogspot.com/2012/04/faster-emulator-with-better-hardware.html">
-                                          <div class="feed-image" style="background:url('../images/emulator-wvga800l.png') no-repeat 0 0">
-                                          </div>
-                                          <h4>A Faster Emulator with Better...</h4>
-                                          <p>Today we’re thrilled to announce several significant improvements to the emulator, including a dramatic...</p>
-					</a></li>
-					<li><a href="http://android-developers.blogspot.com/2012/04/android-c2dm-client-login-key.html">
-                                          <div class="feed-image" style="background:url('../images/develop/auth-code.png') no-repeat 0 0">
-                                          </div>
-                                          <h4>Android C2DM — Client Login key...</h4>
-                                          <p>In the upcoming weeks, some of the older Client
-					Login authentication keys will expire. If you generated the token you’re...</p>
-					</a></li>
-					<li><a href="http://android-developers.blogspot.com/2012/04/accessibility-are-you-serving-all-your.html">
-                                          <div class="feed-image">
-                                          </div>
-                                          <h4>Accessibility</h4>
-                                          <p>We recently published some new resources to help developers make their Android applications more accessible... </p>
-					</a></li>
-                                      
-				</ul>
+          <ul>
+            <li><a href="http://android-developers.blogspot.com/2012/10/google-play-seller-support-in-india.html">
+              <div class="feed-image" style="background:url('http://4.bp.blogspot.com/-ekT-9XQi0YY/UH7WT2XjSdI/AAAAAAAABwc/fI5QaPi7QEk/s320/india-apps1.png') no-repeat 0 0"></div>
+              <h4>Google Play Seller Support in India</h4>
+              <p>Developers in India can sell paid applications, in-app products, and subscriptions in Google Play, with monthly payouts to their local bank accounts...</p>
+              </a></li>
+            <li><a href="http://android-developers.blogspot.com/2012/09/google-play-services-and-oauth-identity.html">
+              <div class="feed-image" style="background:url('https://lh4.ggpht.com/7z4NItEg-X21zvFGAarKonk-VaysBYthJ30u1JjaQ0-5fjyHNawnmoNeG--4FCACog=w124') no-repeat 0 0"></div>
+              <h4>Google Play services and OAuth Tools</h4>
+              <p>The rollout of Google Play services to all Android 2.2+ devices worldwide is now complete, and all of those devices now have new tools for working with OAuth 2.0 tokens...</p>
+              </a></li>
+            <li><a href="http://android-developers.blogspot.com/2012/08/creating-your-own-spelling-checker.html">
+              <div class="feed-image" style="background:url('http://2.bp.blogspot.com/-QKlztEdM1aA/UC1bH6Kv4UI/AAAAAAAAADo/fQS8-EfBYIQ/s320/spell-check-framed-new.png') no-repeat 0 0"></div>
+              <h4>Creating A Spelling Checker Service</h4>
+              <p>If you are an IME developer, the Spelling Checker framework gives you a great way to provide an even better experience for your users...</p>
+              </a></li>
+            <li><a href="http://android-developers.blogspot.com/2012/04/accessibility-are-you-serving-all-your.html">
+              <div class="feed-image"></div>
+              <h4>Accessibility</h4>
+              <p>We recently published some new resources to help developers make their Android applications more accessible... </p>
+              </a></li>                         
+          </ul>
                                 <!-- FEATURED DOCS -->
-				<ul>
-					<li><a href="{@docRoot}guide/google/play/billing/index.html">
-						<h4>Google Play In-app Billing</h4>
-						<p>In-app Billing is a Google Play service that lets you sell digital content from inside your applications. You can sell products as standard in-app products (one-time purchase) or with subscriptions (recurring...</p>
-					</a></li>
-					<li><a href="{@docRoot}guide/topics/providers/contacts-provider.html">
-						<h4>Contacts Provider</h4>
-						<p>The Contacts Provider is a powerful and flexible Android component that manages the device's central repository of data about people. You can use it to build powerful social features...</p>
-					</a></li>
-					<li><a href="{@docRoot}training/efficient-downloads/index.html">
-						<h4>Transferring Data Without Draining the Battery</h4>
-						<p>This training class demonstrates the best practices for scheduling and executing downloads using techniques such as caching, polling, and prefetching.</p>
-					</a></li>
-					<li><a href="{@docRoot}training/backward-compatible-ui/index.html">
-						<h4>Creating Backward-Compatible UIs</h4>
-						<p>This training class demonstrates how to use UI components and APIs available in newer versions of Android in a backward-compatible way, ensuring that your application still runs on previous versions...</p>
-					</a></li>
-				</ul>
+          <ul>
+            <li><a href="{@docRoot}distribute/googleplay/spotlight/tablets.html">
+              <h4>Tablet Stories</h4>
+              <p>More developers are investing in a full tablet experience for their apps. Here are some stories from developers who are seeing real results as they expand their offering to include Android tablets. </p>
+              </a></li>
+            <li><a href="{@docRoot}distribute/googleplay/quality/core.html">
+              <h4>Core App Quality Guidelines</h4>
+              <p>This document helps you assess basic aspects of quality in your app through a compact set of core app quality criteria and associated tests. All Android apps should meet these criteria.</p>
+              </a></li>
+            <li><a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">
+              <h4>Updated Notifications API Guide</h4>
+              <p>The Notifications API Guide is updated to include information about building Jelly Bean rich notifications using the Support Library APIs for backwards-compatibility.</p>
+              </a></li>
+            <li><a href="{@docRoot}guide/topics/ui/dialogs.html">
+              <h4>Updated Dialogs API Guide</h4>
+              <p>The Dialogs API Guide now shows to use DialogFragment class, a simpler way to manage your dialogs and embed them in alternative layouts.</p>
+              </a></li>                                      
+          </ul>
 			</div>
 		</div>
 	</div>	<!-- /news and feature feed -->
@@ -169,10 +154,10 @@
 		</ul>
 		<div class="feed-container">
 			<div class="feed-frame">
-				<ul id="DevelopersLive">
-				</ul>
-				<ul id="VideoPlaylists">
-				</ul>
+              <ul id="DevelopersLive">
+              </ul>
+              <ul id="VideoPlaylists">
+              </ul>
 			</div>
 		</div>
 	</div>
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index dd320a0..aa0d8c3 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -670,6 +670,12 @@
                     ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
                      (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
                      UserHandle.USER_CURRENT);
+
+            // ringtone, notification and system streams are always affected by ringer mode
+            mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_RING)|
+                                            (1 << AudioSystem.STREAM_NOTIFICATION)|
+                                            (1 << AudioSystem.STREAM_SYSTEM);
+
             if (mVoiceCapable) {
                 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
             } else {
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index 079f723..6ff33d7 100755
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -1,5 +1,17 @@
 /*
- * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package com.android.server;
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index b9f5b5b..749dc66 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -602,6 +602,15 @@
         }
     }
 
+    void updateOptionsLocked(ActivityOptions options) {
+        if (options != null) {
+            if (pendingOptions != null) {
+                pendingOptions.abort();
+            }
+            pendingOptions = options;
+        }
+    }
+
     void applyOptionsLocked() {
         if (pendingOptions != null) {
             final int animationType = pendingOptions.getAnimationType();
@@ -653,6 +662,12 @@
         }
     }
 
+    ActivityOptions takeOptionsLocked() {
+        ActivityOptions opts = pendingOptions;
+        pendingOptions = null;
+        return opts;
+    }
+
     void removeUriPermissionsLocked() {
         if (uriPermissions != null) {
             uriPermissions.removeUriPermissionsLocked();
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 4bcb339..4546dc3 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1963,6 +1963,8 @@
         int taskTopI = -1;
         int replyChainEnd = -1;
         int lastReparentPos = -1;
+        ActivityOptions topOptions = null;
+        boolean canMoveOptions = true;
         for (int i=mHistory.size()-1; i>=-1; i--) {
             ActivityRecord below = i >= 0 ? mHistory.get(i) : null;
             
@@ -2048,6 +2050,7 @@
                         }
                         int dstPos = 0;
                         ThumbnailHolder curThumbHolder = target.thumbHolder;
+                        boolean gotOptions = !canMoveOptions;
                         for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
                             p = mHistory.get(srcPos);
                             if (p.finishing) {
@@ -2057,6 +2060,13 @@
                                     + " out to target's task " + target.task);
                             p.setTask(target.task, curThumbHolder, false);
                             curThumbHolder = p.thumbHolder;
+                            canMoveOptions = false;
+                            if (!gotOptions && topOptions == null) {
+                                topOptions = p.takeOptionsLocked();
+                                if (topOptions != null) {
+                                    gotOptions = true;
+                                }
+                            }
                             if (DEBUG_ADD_REMOVE) {
                                 RuntimeException here = new RuntimeException("here");
                                 here.fillInStackTrace();
@@ -2101,11 +2111,19 @@
                             replyChainEnd = targetI;
                         }
                         ActivityRecord p = null;
+                        boolean gotOptions = !canMoveOptions;
                         for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
                             p = mHistory.get(srcPos);
                             if (p.finishing) {
                                 continue;
                             }
+                            canMoveOptions = false;
+                            if (!gotOptions && topOptions == null) {
+                                topOptions = p.takeOptionsLocked();
+                                if (topOptions != null) {
+                                    gotOptions = true;
+                                }
+                            }
                             if (finishActivityLocked(p, srcPos,
                                     Activity.RESULT_CANCELED, null, "reset", false)) {
                                 replyChainEnd--;
@@ -2245,7 +2263,17 @@
             target = below;
             targetI = i;
         }
-        
+
+        if (topOptions != null) {
+            // If we got some ActivityOptions from an activity on top that
+            // was removed from the task, propagate them to the new real top.
+            if (taskTop != null) {
+                taskTop.updateOptionsLocked(topOptions);
+            } else {
+                topOptions.abort();
+            }
+        }
+
         return taskTop;
     }
     
@@ -2296,6 +2324,10 @@
                     if (r.finishing) {
                         continue;
                     }
+                    ActivityOptions opts = r.takeOptionsLocked();
+                    if (opts != null) {
+                        ret.updateOptionsLocked(opts);
+                    }
                     if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
                             null, "clear", false)) {
                         i--;
diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java
index 0247911..71a6a01 100644
--- a/services/java/com/android/server/pm/Installer.java
+++ b/services/java/com/android/server/pm/Installer.java
@@ -243,14 +243,14 @@
         return execute(builder.toString());
     }
 
-    public int fixUid(String name, int uid, int userId) {
+    public int fixUid(String name, int uid, int gid) {
         StringBuilder builder = new StringBuilder("fixuid");
         builder.append(' ');
         builder.append(name);
         builder.append(' ');
         builder.append(uid);
         builder.append(' ');
-        builder.append(userId);
+        builder.append(gid);
         return execute(builder.toString());
     }
 
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 9e2ad8e..6ef39ac 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1008,8 +1008,6 @@
             mHandler = new PackageHandler(mHandlerThread.getLooper());
 
             File dataDir = Environment.getDataDirectory();
-            mAppInstallDir = new File(dataDir, "app");
-            mAppLibInstallDir = new File(dataDir, "app-lib");
             mAppDataDir = new File(dataDir, "data");
             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
             mUserAppDataDir = new File(dataDir, "user");
@@ -1220,6 +1218,8 @@
                 }
             }
 
+            mAppInstallDir = new File(dataDir, "app");
+            mAppLibInstallDir = new File(dataDir, "app-lib");
             //look for any incomplete package installations
             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
             //clean up list
@@ -3577,22 +3577,22 @@
         }
     }
 
-    private int createDataDirForUserLI(String packageName, int uid, int userId) {
-        if (userId == 0) {
-            return mInstaller.install(packageName, uid, uid);
-        } else {
-            return mInstaller.createUserData(packageName, UserHandle.getUid(userId, uid), userId);
-        }
-    }
-
     private int createDataDirsLI(String packageName, int uid) {
-        for (int userId : sUserManager.getUserIds()) {
-            int res = createDataDirForUserLI(packageName, uid, userId);
-            if (res < 0) {
-                return res;
+        int[] users = sUserManager.getUserIds();
+        int res = mInstaller.install(packageName, uid, uid);
+        if (res < 0) {
+            return res;
+        }
+        for (int user : users) {
+            if (user != 0) {
+                res = mInstaller.createUserData(packageName,
+                        UserHandle.getUid(user, uid), user);
+                if (res < 0) {
+                    return res;
+                }
             }
         }
-        return 0;
+        return res;
     }
 
     private int removeDataDirsLI(String packageName) {
@@ -3931,49 +3931,134 @@
             pkg.applicationInfo.dataDir = dataPath.getPath();
         } else {
             // This is a normal package, need to make its data directory.
-            dataPath = getDataPathForPackage(pkg.packageName, UserHandle.USER_OWNER);
+            dataPath = getDataPathForPackage(pkg.packageName, 0);
 
-            if (!ensureDataDirExistsForAllUsers(pkg.packageName, pkg.applicationInfo.uid)) {
-                if (DEBUG_PACKAGE_SCANNING) {
-                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
-                        Log.v(TAG, "Want this data dir: " + dataPath);
-                    }
+            boolean uidError = false;
+
+            if (dataPath.exists()) {
+                int currentUid = 0;
+                try {
+                    StructStat stat = Libcore.os.stat(dataPath.getPath());
+                    currentUid = stat.st_uid;
+                } catch (ErrnoException e) {
+                    Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
                 }
 
-                // Error from installer
-                mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
-                return null;
-            } else {
+                // If we have mismatched owners for the data path, we have a problem.
+                if (currentUid != pkg.applicationInfo.uid) {
+                    boolean recovered = false;
+                    if (currentUid == 0) {
+                        // The directory somehow became owned by root.  Wow.
+                        // This is probably because the system was stopped while
+                        // installd was in the middle of messing with its libs
+                        // directory.  Ask installd to fix that.
+                        int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
+                                pkg.applicationInfo.uid);
+                        if (ret >= 0) {
+                            recovered = true;
+                            String msg = "Package " + pkg.packageName
+                                    + " unexpectedly changed to uid 0; recovered to " +
+                                    + pkg.applicationInfo.uid;
+                            reportSettingsProblem(Log.WARN, msg);
+                        }
+                    }
+                    if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
+                            || (scanMode&SCAN_BOOTING) != 0)) {
+                        // If this is a system app, we can at least delete its
+                        // current data so the application will still work.
+                        int ret = removeDataDirsLI(pkgName);
+                        if (ret >= 0) {
+                            // TODO: Kill the processes first
+                            // Old data gone!
+                            String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
+                                    ? "System package " : "Third party package ";
+                            String msg = prefix + pkg.packageName
+                                    + " has changed from uid: "
+                                    + currentUid + " to "
+                                    + pkg.applicationInfo.uid + "; old data erased";
+                            reportSettingsProblem(Log.WARN, msg);
+                            recovered = true;
+
+                            // And now re-install the app.
+                            ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid);
+                            if (ret == -1) {
+                                // Ack should not happen!
+                                msg = prefix + pkg.packageName
+                                        + " could not have data directory re-created after delete.";
+                                reportSettingsProblem(Log.WARN, msg);
+                                mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+                                return null;
+                            }
+                        }
+                        if (!recovered) {
+                            mHasSystemUidErrors = true;
+                        }
+                    } else if (!recovered) {
+                        // If we allow this install to proceed, we will be broken.
+                        // Abort, abort!
+                        mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
+                        return null;
+                    }
+                    if (!recovered) {
+                        pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
+                            + pkg.applicationInfo.uid + "/fs_"
+                            + currentUid;
+                        pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
+                        String msg = "Package " + pkg.packageName
+                                + " has mismatched uid: "
+                                + currentUid + " on disk, "
+                                + pkg.applicationInfo.uid + " in settings";
+                        // writer
+                        synchronized (mPackages) {
+                            mSettings.mReadMessages.append(msg);
+                            mSettings.mReadMessages.append('\n');
+                            uidError = true;
+                            if (!pkgSetting.uidError) {
+                                reportSettingsProblem(Log.ERROR, msg);
+                            }
+                        }
+                    }
+                }
                 pkg.applicationInfo.dataDir = dataPath.getPath();
+            } else {
+                if (DEBUG_PACKAGE_SCANNING) {
+                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
+                        Log.v(TAG, "Want this data dir: " + dataPath);
+                }
+                //invoke installer to do the actual installation
+                int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid);
+                if (ret < 0) {
+                    // Error from installer
+                    mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+                    return null;
+                }
+
+                if (dataPath.exists()) {
+                    pkg.applicationInfo.dataDir = dataPath.getPath();
+                } else {
+                    Slog.w(TAG, "Unable to create data directory: " + dataPath);
+                    pkg.applicationInfo.dataDir = null;
+                }
             }
 
-            final boolean isSystemApp = (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
-            final boolean isBootScan = (scanMode & SCAN_BOOTING) != 0;
-
-            final boolean uidCorrect = ensureDataDirUidIsCorrectForAllUsers(pkg.packageName,
-                    pkg.applicationInfo.uid, isSystemApp, isBootScan);
-            if (!uidCorrect) {
-                pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" + pkg.applicationInfo.uid
-                        + "/fs_mismatched";
-                pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
-            }
-
-            pkgSetting.uidError = !uidCorrect;
-
             /*
-             * Set the native library dir to the default if we got here without
-             * anyone telling us different (e.g., apps stored on SD card have
-             * their native libraries stored in the ASEC container with the
-             * APK). This happens during an upgrade from a package settings file
-             * that doesn't have a native library path attribute at all.
+             * Set the data dir to the default "/data/data/<package name>/lib"
+             * if we got here without anyone telling us different (e.g., apps
+             * stored on SD card have their native libraries stored in the ASEC
+             * container with the APK).
+             *
+             * This happens during an upgrade from a package settings file that
+             * doesn't have a native library path attribute at all.
              */
-            if (pkg.applicationInfo.nativeLibraryDir == null) {
+            if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
                 if (pkgSetting.nativeLibraryPathString == null) {
                     setInternalAppNativeLibraryPath(pkg, pkgSetting);
                 } else {
                     pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
                 }
             }
+
+            pkgSetting.uidError = uidError;
         }
 
         String path = scanFile.getPath();
@@ -4362,100 +4447,6 @@
         return pkg;
     }
 
-    /**
-     * Checks to see whether a package data directory is owned by the correct
-     * user. If it isn't, it will attempt to fix it if it's a system application
-     * or if this is the boot scan.
-     *
-     * @return {@code true} if successful, {@code false} if recovery failed
-     */
-    private boolean ensureDataDirUidIsCorrectForAllUsers(String packageName, int appUid,
-            boolean isSystemApp, boolean isBootScan) {
-        boolean mismatch = false;
-
-        for (int userId : sUserManager.getUserIds()) {
-            final File dataPath = getDataPathForPackage(packageName, userId);
-
-            int currentUid = 0;
-            try {
-                final StructStat stat = Libcore.os.stat(dataPath.getPath());
-                currentUid = stat.st_uid;
-            } catch (ErrnoException e) {
-                Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
-            }
-
-            final int expectedUid = UserHandle.getUid(userId, appUid);
-
-            // If we have mismatched owners for the data path, we have a
-            // problem.
-            if (currentUid != expectedUid) {
-                if (currentUid == 0) {
-                    // The directory somehow became owned by root. Wow.
-                    // This is probably because the system was stopped while
-                    // installd was in the middle of messing with its libs
-                    // directory. Ask installd to fix that.
-                    final int ret;
-                    synchronized (mInstaller) {
-                        ret = mInstaller.fixUid(packageName, expectedUid, userId);
-                    }
-                    if (ret >= 0) {
-                        String msg = "Package " + packageName
-                                + " unexpectedly changed to uid 0; recovered to " + expectedUid;
-                        reportSettingsProblem(Log.WARN, msg);
-                    } else {
-                        mismatch = true;
-                        String prefix = isSystemApp ? "System package " : "Third party package ";
-                        String msg = prefix + packageName + " has changed from uid: " + currentUid
-                                + " to " + expectedUid;
-                        reportSettingsProblem(Log.WARN, msg);
-                    }
-                }
-            }
-        }
-
-        if (mismatch) {
-            if (isSystemApp || isBootScan) {
-                // If this is a system app, we can at least delete its
-                // current data so the application will still work.
-                int ret;
-                synchronized (mInstallLock) {
-                    ret = removeDataDirsLI(packageName);
-                }
-                if (ret >= 0) {
-                    // TODO: Kill the processes first
-                    // Old data gone!
-                    String prefix = isSystemApp
-                            ? "System package " : "Third party package ";
-                    String msg = prefix + packageName + " old data erased";
-                    reportSettingsProblem(Log.WARN, msg);
-
-                    // And now re-install the app.
-                    synchronized (mInstallLock) {
-                        ret = createDataDirsLI(packageName, appUid);
-                    }
-                    if (ret == -1) {
-                        // Ack should not happen!
-                        msg = prefix + packageName
-                                + " could not have data directory re-created after delete.";
-                        reportSettingsProblem(Log.WARN, msg);
-                        mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
-                        return false;
-                    }
-                } else {
-                    mHasSystemUidErrors = true;
-                    return false;
-                }
-            } else {
-                // If we allow this install to proceed, we will be broken.
-                // Abort, abort!
-                mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
-                return false;
-            }
-        }
-
-        return true;
-    }
-
     private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
             PackageSetting pkgSetting) {
         final String apkLibPath = getApkName(pkgSetting.codePathString);
@@ -7512,22 +7503,6 @@
         PackageRemovedInfo removedInfo;
     }
 
-    private boolean ensureDataDirExistsForAllUsers(String packageName, int uid) {
-        boolean exists = true;
-        for (int userId : sUserManager.getUserIds()) {
-            final File dataPath = getDataPathForPackage(packageName, userId);
-            if (!dataPath.exists()) {
-                synchronized (mInstallLock) {
-                    if (createDataDirForUserLI(packageName, uid, userId) < 0) {
-                        Slog.e(TAG, "Couldn't create data path " + dataPath.getPath());
-                    }
-                }
-                exists &= dataPath.exists();
-            }
-        }
-        return exists;
-    }
-
     /*
      * Install a non-existing package.
      */
@@ -7537,8 +7512,7 @@
         // Remember this for later, in case we need to rollback this install
         String pkgName = pkg.packageName;
 
-        boolean dataDirExists = ensureDataDirExistsForAllUsers(pkg.packageName,
-                pkg.applicationInfo.uid);
+        boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
         synchronized(mPackages) {
             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
                 // A package with the same name is already installed, though
@@ -8291,7 +8265,7 @@
         removePackageDataLI(ps, outInfo, flags, writeSettings);
 
         // Delete application code and resources
-        if (deleteCodeAndResources) {
+        if (deleteCodeAndResources && (outInfo != null)) {
             outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString,
                     ps.resourcePathString, ps.nativeLibraryPathString);
         }