Merge "Add initial plumbing for brightness keys"
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index b5574cf..1c5f32e 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -488,11 +488,11 @@
             IActivityManager.WaitResult result = null;
             int res;
             if (mWaitOption) {
-                result = mAm.startActivityAndWait(null, intent, mimeType,
+                result = mAm.startActivityAndWait(null, null, intent, mimeType,
                             null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
                 res = result.result;
             } else {
-                res = mAm.startActivityAsUser(null, intent, mimeType,
+                res = mAm.startActivityAsUser(null, null, intent, mimeType,
                         null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
             }
             PrintStream out = mWaitOption ? System.out : System.err;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 18ccd53..87c2d8c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3740,7 +3740,7 @@
             try {
                 intent.setAllowFds(false);
                 result = ActivityManagerNative.getDefault()
-                    .startActivity(mMainThread.getApplicationThread(),
+                    .startActivity(mMainThread.getApplicationThread(), getBasePackageName(),
                             intent, intent.resolveTypeIfNeeded(getContentResolver()),
                             mToken, mEmbeddedID, requestCode,
                             ActivityManager.START_FLAG_ONLY_IF_NEEDED, null, null,
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index d8e2239..c9930e9 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -116,6 +116,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent intent = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
@@ -127,7 +128,7 @@
                     ? data.readFileDescriptor() : null;
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
-            int result = startActivity(app, intent, resolvedType,
+            int result = startActivity(app, callingPackage, intent, resolvedType,
                     resultTo, resultWho, requestCode, startFlags,
                     profileFile, profileFd, options);
             reply.writeNoException();
@@ -140,6 +141,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent intent = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
@@ -152,7 +154,7 @@
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
-            int result = startActivityAsUser(app, intent, resolvedType,
+            int result = startActivityAsUser(app, callingPackage, intent, resolvedType,
                     resultTo, resultWho, requestCode, startFlags,
                     profileFile, profileFd, options, userId);
             reply.writeNoException();
@@ -165,6 +167,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent intent = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
@@ -177,7 +180,7 @@
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
-            WaitResult result = startActivityAndWait(app, intent, resolvedType,
+            WaitResult result = startActivityAndWait(app, callingPackage, intent, resolvedType,
                     resultTo, resultWho, requestCode, startFlags,
                     profileFile, profileFd, options, userId);
             reply.writeNoException();
@@ -190,6 +193,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent intent = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
@@ -200,7 +204,7 @@
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
-            int result = startActivityWithConfig(app, intent, resolvedType,
+            int result = startActivityWithConfig(app, callingPackage, intent, resolvedType,
                     resultTo, resultWho, requestCode, startFlags, config, options, userId);
             reply.writeNoException();
             reply.writeInt(result);
@@ -1526,13 +1530,14 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent[] intents = data.createTypedArray(Intent.CREATOR);
             String[] resolvedTypes = data.createStringArray();
             IBinder resultTo = data.readStrongBinder();
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
-            int result = startActivities(app, intents, resolvedTypes, resultTo,
+            int result = startActivities(app, callingPackage, intents, resolvedTypes, resultTo,
                     options, userId);
             reply.writeNoException();
             reply.writeInt(result);
@@ -1784,6 +1789,15 @@
             return true;
         }
 
+        case GET_LAUNCHED_FROM_PACKAGE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            String res = getLaunchedFromPackage(token);
+            reply.writeNoException();
+            reply.writeString(res);
+            return true;
+        }
+
         case REGISTER_USER_SWITCH_OBSERVER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
@@ -1873,7 +1887,7 @@
         return mRemote;
     }
 
-    public int startActivity(IApplicationThread caller, Intent intent,
+    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
@@ -1881,6 +1895,7 @@
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         intent.writeToParcel(data, 0);
         data.writeString(resolvedType);
         data.writeStrongBinder(resultTo);
@@ -1908,7 +1923,7 @@
         return result;
     }
 
-    public int startActivityAsUser(IApplicationThread caller, Intent intent,
+    public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException {
@@ -1916,6 +1931,7 @@
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         intent.writeToParcel(data, 0);
         data.writeString(resolvedType);
         data.writeStrongBinder(resultTo);
@@ -1943,14 +1959,15 @@
         data.recycle();
         return result;
     }
-    public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho,
+    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         intent.writeToParcel(data, 0);
         data.writeString(resolvedType);
         data.writeStrongBinder(resultTo);
@@ -1978,14 +1995,15 @@
         data.recycle();
         return result;
     }
-    public int startActivityWithConfig(IApplicationThread caller, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho,
+    public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int startFlags, Configuration config,
             Bundle options, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         intent.writeToParcel(data, 0);
         data.writeString(resolvedType);
         data.writeStrongBinder(resultTo);
@@ -3771,13 +3789,14 @@
         return res;
     }
     
-    public int startActivities(IApplicationThread caller,
+    public int startActivities(IApplicationThread caller, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
             Bundle options, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         data.writeTypedArray(intents, 0);
         data.writeStringArray(resolvedTypes);
         data.writeStrongBinder(resultTo);
@@ -4123,6 +4142,19 @@
         return result;
     }
 
+    public String getLaunchedFromPackage(IBinder activityToken) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(activityToken);
+        mRemote.transact(GET_LAUNCHED_FROM_PACKAGE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        String result = reply.readString();
+        data.recycle();
+        reply.recycle();
+        return result;
+    }
+
     public void registerUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index b1d0305..a81b6fe 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.Manifest;
 import com.android.internal.app.IAppOpsService;
 
 import java.util.ArrayList;
@@ -47,35 +48,83 @@
     public static final int OP_READ_CALENDAR = 8;
     public static final int OP_WRITE_CALENDAR = 9;
     public static final int OP_WIFI_SCAN = 10;
+    public static final int OP_POST_NOTIFICATION = 11;
+    public static final int OP_NEIGHBORING_CELLS = 12;
+    public static final int OP_CALL_PHONE = 13;
+    /** @hide */
+    public static final int _NUM_OP = 14;
 
+    /**
+     * This maps each operation to the operation that serves as the
+     * switch to determine whether it is allowed.  Generally this is
+     * a 1:1 mapping, but for some things (like location) that have
+     * multiple low-level operations being tracked that should be
+     * presented to hte user as one switch then this can be used to
+     * make them all controlled by the same single operation.
+     */
+    private static int[] sOpToSwitch = new int[] {
+            OP_COARSE_LOCATION,
+            OP_COARSE_LOCATION,
+            OP_COARSE_LOCATION,
+            OP_VIBRATE,
+            OP_READ_CONTACTS,
+            OP_WRITE_CONTACTS,
+            OP_READ_CALL_LOG,
+            OP_WRITE_CALL_LOG,
+            OP_READ_CALENDAR,
+            OP_WRITE_CALENDAR,
+            OP_COARSE_LOCATION,
+            OP_POST_NOTIFICATION,
+            OP_COARSE_LOCATION,
+            OP_CALL_PHONE,
+    };
+
+    /**
+     * This provides a simple name for each operation to be used
+     * in debug output.
+     */
     private static String[] sOpNames = new String[] {
-        "COARSE_LOCATION",
-        "FINE_LOCATION",
-        "GPS",
-        "VIBRATE",
-        "READ_CONTACTS",
-        "WRITE_CONTACTS",
-        "READ_CALL_LOG",
-        "WRITE_CALL_LOG",
-        "READ_CALENDAR",
-        "WRITE_CALENDAR",
-        "WIFI_SCAN",
+            "COARSE_LOCATION",
+            "FINE_LOCATION",
+            "GPS",
+            "VIBRATE",
+            "READ_CONTACTS",
+            "WRITE_CONTACTS",
+            "READ_CALL_LOG",
+            "WRITE_CALL_LOG",
+            "READ_CALENDAR",
+            "WRITE_CALENDAR",
+            "WIFI_SCAN",
+            "POST_NOTIFICATION",
+            "NEIGHBORING_CELLS",
+            "CALL_PHONE",
     };
 
+    /**
+     * This optionally maps a permission to an operation.  If there
+     * is no permission associated with an operation, it is null.
+     */
     private static String[] sOpPerms = new String[] {
-        android.Manifest.permission.ACCESS_COARSE_LOCATION,
-        android.Manifest.permission.ACCESS_FINE_LOCATION,
-        android.Manifest.permission.ACCESS_FINE_LOCATION,
-        android.Manifest.permission.VIBRATE,
-        android.Manifest.permission.READ_CONTACTS,
-        android.Manifest.permission.WRITE_CONTACTS,
-        android.Manifest.permission.READ_CALL_LOG,
-        android.Manifest.permission.WRITE_CALL_LOG,
-        android.Manifest.permission.READ_CALENDAR,
-        android.Manifest.permission.WRITE_CALENDAR,
-        android.Manifest.permission.ACCESS_WIFI_STATE,
+            android.Manifest.permission.ACCESS_COARSE_LOCATION,
+            android.Manifest.permission.ACCESS_FINE_LOCATION,
+            null,
+            android.Manifest.permission.VIBRATE,
+            android.Manifest.permission.READ_CONTACTS,
+            android.Manifest.permission.WRITE_CONTACTS,
+            android.Manifest.permission.READ_CALL_LOG,
+            android.Manifest.permission.WRITE_CALL_LOG,
+            android.Manifest.permission.READ_CALENDAR,
+            android.Manifest.permission.WRITE_CALENDAR,
+            null, // no permission required for notifications
+            android.Manifest.permission.ACCESS_WIFI_STATE,
+            null, // neighboring cells shares the coarse location perm
+            android.Manifest.permission.CALL_PHONE,
     };
 
+    public static int opToSwitch(int op) {
+        return sOpToSwitch[op];
+    }
+
     public static String opToName(int op) {
         return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
     }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index e03d3fd..2cf9f59 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -963,7 +963,7 @@
     public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
         try {
             ActivityManagerNative.getDefault().startActivityAsUser(
-                mMainThread.getApplicationThread(), intent,
+                mMainThread.getApplicationThread(), getBasePackageName(), intent,
                 intent.resolveTypeIfNeeded(getContentResolver()),
                 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, options,
                 user.getIdentifier());
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5a493294..e58ff62 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -51,19 +51,19 @@
  * {@hide}
  */
 public interface IActivityManager extends IInterface {
-    public int startActivity(IApplicationThread caller,
+    public int startActivity(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int flags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options) throws RemoteException;
-    public int startActivityAsUser(IApplicationThread caller,
+    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int flags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
-    public WaitResult startActivityAndWait(IApplicationThread caller,
+    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int flags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
-    public int startActivityWithConfig(IApplicationThread caller,
+    public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int startFlags, Configuration newConfig,
             Bundle options, int userId) throws RemoteException;
@@ -310,7 +310,7 @@
     public boolean dumpHeap(String process, int userId, boolean managed, String path,
         ParcelFileDescriptor fd) throws RemoteException;
 
-    public int startActivities(IApplicationThread caller,
+    public int startActivities(IApplicationThread caller, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
             Bundle options, int userId) throws RemoteException;
 
@@ -357,9 +357,10 @@
     public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
             throws RemoteException;
 
-    // This is not public because you need to be very careful in how you
+    // These are not public because you need to be very careful in how you
     // manage your activity to make sure it is always the uid you expect.
     public int getLaunchedFromUid(IBinder activityToken) throws RemoteException;
+    public String getLaunchedFromPackage(IBinder activityToken) throws RemoteException;
 
     public void registerUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException;
     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException;
@@ -630,4 +631,5 @@
     int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160;
     int GET_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
     int REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
+    int GET_LAUNCHED_FROM_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+163;
 }
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 62d4962..d400eba 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -28,11 +28,11 @@
 
     void enqueueToast(String pkg, ITransientNotification callback, int duration);
     void cancelToast(String pkg, ITransientNotification callback);
-    void enqueueNotificationWithTag(String pkg, String tag, int id,
+    void enqueueNotificationWithTag(String pkg, String basePkg, String tag, int id,
             in Notification notification, inout int[] idReceived, int userId);
     void cancelNotificationWithTag(String pkg, String tag, int id, int userId);
 
-    void setNotificationsEnabledForPackage(String pkg, boolean enabled);
-    boolean areNotificationsEnabledForPackage(String pkg);
+    void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled);
+    boolean areNotificationsEnabledForPackage(String pkg, int uid);
 }
 
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index a2eeddd..e7bf305 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1413,7 +1413,7 @@
             intent.setAllowFds(false);
             intent.migrateExtraStreamToClipData();
             int result = ActivityManagerNative.getDefault()
-                .startActivity(whoThread, intent,
+                .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
                         requestCode, 0, null, null, options);
@@ -1471,15 +1471,16 @@
                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
             }
             int result = ActivityManagerNative.getDefault()
-                .startActivities(whoThread, intents, resolvedTypes, token, options,
-                        userId);
+                .startActivities(whoThread, who.getBasePackageName(), intents, resolvedTypes,
+                        token, options, userId);
             checkStartActivityResult(result, intents[0]);
         } catch (RemoteException e) {
         }
     }
 
     /**
-     * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int)},
+     * Like {@link #execStartActivity(android.content.Context, android.os.IBinder,
+     * android.os.IBinder, Fragment, android.content.Intent, int, android.os.Bundle)},
      * but for calls from a {#link Fragment}.
      * 
      * @param who The Context from which the activity is being started.
@@ -1528,7 +1529,7 @@
             intent.setAllowFds(false);
             intent.migrateExtraStreamToClipData();
             int result = ActivityManagerNative.getDefault()
-                .startActivity(whoThread, intent,
+                .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mWho : null,
                         requestCode, 0, null, null, options);
@@ -1588,7 +1589,7 @@
             intent.setAllowFds(false);
             intent.migrateExtraStreamToClipData();
             int result = ActivityManagerNative.getDefault()
-                .startActivityAsUser(whoThread, intent,
+                .startActivityAsUser(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
                         requestCode, 0, null, null, options, user.getIdentifier());
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 0acad75..5e69128 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -129,8 +129,8 @@
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
         try {
-            service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut,
-                    UserHandle.myUserId());
+            service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id,
+                    notification, idOut, UserHandle.myUserId());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
             }
@@ -151,8 +151,8 @@
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
         try {
-            service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut,
-                    user.getIdentifier());
+            service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id,
+                    notification, idOut, user.getIdentifier());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
             }
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 6b00c58..761faaf 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -813,6 +813,22 @@
             }
         }
 
+        /**
+         * @hide
+         */
+        @Override
+        public void vibrate(int owningUid, String owningPackage, long milliseconds) {
+            vibrate(milliseconds);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
+            vibrate(pattern, repeat);
+        }
+
         @Override
         public void cancel() {
             try {
diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl
index 15cedf9..456ffb1 100644
--- a/core/java/android/os/IVibratorService.aidl
+++ b/core/java/android/os/IVibratorService.aidl
@@ -20,8 +20,8 @@
 interface IVibratorService
 {
     boolean hasVibrator();
-    void vibrate(String packageName, long milliseconds, IBinder token);
-    void vibratePattern(String packageName, in long[] pattern, int repeat, IBinder token);
+    void vibrate(int uid, String packageName, long milliseconds, IBinder token);
+    void vibratePattern(int uid, String packageName, in long[] pattern, int repeat, IBinder token);
     void cancelVibrate(IBinder token);
 }
 
diff --git a/core/java/android/os/NullVibrator.java b/core/java/android/os/NullVibrator.java
index 8de4e06..ac6027f 100644
--- a/core/java/android/os/NullVibrator.java
+++ b/core/java/android/os/NullVibrator.java
@@ -49,6 +49,22 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public void vibrate(int owningUid, String owningPackage, long milliseconds) {
+        vibrate(milliseconds);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
+        vibrate(pattern, repeat);
+    }
+
     @Override
     public void cancel() {
     }
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 08eba4f..e66fb285 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.app.ActivityThread;
 import android.content.Context;
 import android.util.Log;
 
@@ -32,7 +33,7 @@
     private final Binder mToken = new Binder();
 
     public SystemVibrator() {
-        mPackageName = null;
+        mPackageName = ActivityThread.currentPackageName();
         mService = IVibratorService.Stub.asInterface(
                 ServiceManager.getService("vibrator"));
     }
@@ -58,19 +59,35 @@
 
     @Override
     public void vibrate(long milliseconds) {
+        vibrate(Process.myUid(), mPackageName, milliseconds);
+    }
+
+    @Override
+    public void vibrate(long[] pattern, int repeat) {
+        vibrate(Process.myUid(), mPackageName, pattern, repeat);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void vibrate(int owningUid, String owningPackage, long milliseconds) {
         if (mService == null) {
             Log.w(TAG, "Failed to vibrate; no vibrator service.");
             return;
         }
         try {
-            mService.vibrate(mPackageName, milliseconds, mToken);
+            mService.vibrate(owningUid, owningPackage, milliseconds, mToken);
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to vibrate.", e);
         }
     }
 
+    /**
+     * @hide
+     */
     @Override
-    public void vibrate(long[] pattern, int repeat) {
+    public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
         if (mService == null) {
             Log.w(TAG, "Failed to vibrate; no vibrator service.");
             return;
@@ -80,7 +97,7 @@
         // anyway
         if (repeat < pattern.length) {
             try {
-                mService.vibratePattern(mPackageName, pattern, repeat, mToken);
+                mService.vibratePattern(owningUid, owningPackage, pattern, repeat, mToken);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to vibrate.", e);
             }
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index b67be4b..6650fca 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -73,6 +73,20 @@
     public abstract void vibrate(long[] pattern, int repeat);
 
     /**
+     * @hide
+     * Like {@link #vibrate(long)}, but allowing the caller to specify that
+     * the vibration is owned by someone else.
+     */
+    public abstract void vibrate(int owningUid, String owningPackage, long milliseconds);
+
+    /**
+     * @hide
+     * Like {@link #vibrate(long[], int)}, but allowing the caller to specify that
+     * the vibration is owned by someone else.
+     */
+    public abstract void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat);
+
+    /**
      * Turn the vibrator off.
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#VIBRATE}.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 02be4db..bd28abc 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -135,6 +135,16 @@
      */
     public interface WindowState {
         /**
+         * Return the uid of the app that owns this window.
+         */
+        int getOwningUid();
+
+        /**
+         * Return the package name of the app that owns this window.
+         */
+        String getOwningPackage();
+
+        /**
          * Perform standard frame computation.  The result can be obtained with
          * getFrame() if so desired.  Must be called with the window manager
          * lock held.
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 7a3d7c3..4e7ff08 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -1914,8 +1914,16 @@
                 return "ACTION_SCROLL_FORWARD";
             case ACTION_SCROLL_BACKWARD:
                 return "ACTION_SCROLL_BACKWARD";
+            case ACTION_CUT:
+                return "ACTION_CUT";
+            case ACTION_COPY:
+                return "ACTION_COPY";
+            case ACTION_PASTE:
+                return "ACTION_PASTE";
+            case ACTION_SET_SELECTION:
+                return "ACTION_SET_SELECTION";
             default:
-                throw new IllegalArgumentException("Unknown action: " + action);
+                return"ACTION_UNKNOWN";
         }
     }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index fc0ff55..16007c4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 96;
+    private static final int DATABASE_VERSION = 97;
 
     private Context mContext;
     private int mUserHandle;
@@ -1536,6 +1536,11 @@
             upgradeVersion = 96;
         }
 
+        if (upgradeVersion == 96) {
+            // NOP bump due to a reverted change that some people got on upgrade.
+            upgradeVersion = 97;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 776cf36..0944b40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -120,7 +120,7 @@
 
                 int[] idOut = new int[1];
                 mNotificationService.enqueueNotificationWithTag(
-                        mContext.getPackageName(),
+                        mContext.getPackageName(), mContext.getBasePackageName(),
                         null, 
                         GPS_NOTIFICATION_ID, 
                         n,
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index d1fb2b0..8135d22 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -4408,7 +4408,7 @@
                     sendCloseSystemWindows();
                 }
                 int result = ActivityManagerNative.getDefault()
-                        .startActivityAsUser(null, mHomeIntent,
+                        .startActivityAsUser(null, null, mHomeIntent,
                                 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
                                 null, null, 0,
                                 ActivityManager.START_FLAG_ONLY_IF_NEEDED,
@@ -4480,12 +4480,21 @@
             default:
                 return false;
         }
+        int owningUid;
+        String owningPackage;
+        if (win != null) {
+            owningUid = win.getOwningUid();
+            owningPackage = win.getOwningPackage();
+        } else {
+            owningUid = android.os.Process.myUid();
+            owningPackage = mContext.getBasePackageName();
+        }
         if (pattern.length == 1) {
             // One-shot vibration
-            mVibrator.vibrate(pattern[0]);
+            mVibrator.vibrate(owningUid, owningPackage, pattern[0]);
         } else {
             // Pattern vibration
-            mVibrator.vibrate(pattern, -1);
+            mVibrator.vibrate(owningUid, owningPackage, pattern, -1);
         }
         return true;
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
index 4c19caa..6539db3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
@@ -219,6 +219,7 @@
                 try {
                     WaitResult result = ActivityManagerNative.getDefault().startActivityAndWait(
                             null /*caller*/,
+                            null /*caller pkg*/,
                             intent,
                             intent.resolveTypeIfNeeded(getContext().getContentResolver()),
                             null /*resultTo*/,
diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java
index bf2a5ae..335917e 100644
--- a/services/java/com/android/server/AppOpsService.java
+++ b/services/java/com/android/server/AppOpsService.java
@@ -203,9 +203,9 @@
 
     @Override
     public void setMode(int code, int uid, String packageName, int mode) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
-            Op op = getOpLocked(code, uid, packageName, true);
+            Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, true);
             if (op != null) {
                 if (op.mode != mode) {
                     op.mode = mode;
@@ -217,9 +217,9 @@
 
     @Override
     public int checkOperation(int code, int uid, String packageName) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
-            Op op = getOpLocked(code, uid, packageName, false);
+            Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false);
             if (op == null) {
                 return AppOpsManager.MODE_ALLOWED;
             }
@@ -229,24 +229,27 @@
 
     @Override
     public int noteOperation(int code, int uid, String packageName) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
-            Op op = getOpLocked(code, uid, packageName, true);
-            if (op == null) {
+            Ops ops = getOpsLocked(uid, packageName, true);
+            if (ops == null) {
                 if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
                         + " package " + packageName);
                 return AppOpsManager.MODE_IGNORED;
             }
+            Op op = getOpLocked(ops, code, true);
             if (op.duration == -1) {
                 Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName
                         + " code " + code + " time=" + op.time + " duration=" + op.duration);
             }
             op.duration = 0;
-            if (op.mode != AppOpsManager.MODE_ALLOWED) {
-                if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " + code
-                        + " uid " + uid + " package " + packageName);
+            final int switchCode = AppOpsManager.opToSwitch(code);
+            final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
+            if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
+                if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
+                        + switchCode + " (" + code + ") uid " + uid + " package " + packageName);
                 op.rejectTime = System.currentTimeMillis();
-                return op.mode;
+                return switchOp.mode;
             }
             if (DEBUG) Log.d(TAG, "noteOperation: allowing code " + code + " uid " + uid
                     + " package " + packageName);
@@ -257,19 +260,22 @@
 
     @Override
     public int startOperation(int code, int uid, String packageName) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
-            Op op = getOpLocked(code, uid, packageName, true);
-            if (op == null) {
+            Ops ops = getOpsLocked(uid, packageName, true);
+            if (ops == null) {
                 if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid
                         + " package " + packageName);
                 return AppOpsManager.MODE_IGNORED;
             }
-            if (op.mode != AppOpsManager.MODE_ALLOWED) {
-                if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code " + code
-                        + " uid " + uid + " package " + packageName);
+            Op op = getOpLocked(ops, code, true);
+            final int switchCode = AppOpsManager.opToSwitch(code);
+            final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
+            if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
+                if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code "
+                        + switchCode + " (" + code + ") uid " + uid + " package " + packageName);
                 op.rejectTime = System.currentTimeMillis();
-                return op.mode;
+                return switchOp.mode;
             }
             if (DEBUG) Log.d(TAG, "startOperation: allowing code " + code + " uid " + uid
                     + " package " + packageName);
@@ -284,7 +290,7 @@
 
     @Override
     public void finishOperation(int code, int uid, String packageName) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
             Op op = getOpLocked(code, uid, packageName, true);
             if (op == null) {
@@ -305,16 +311,15 @@
         }
     }
 
-    private int handleIncomingUid(int uid) {
+    private void verifyIncomingUid(int uid) {
         if (uid == Binder.getCallingUid()) {
-            return uid;
+            return;
         }
         if (Binder.getCallingPid() == Process.myPid()) {
-            return uid;
+            return;
         }
         mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
                 Binder.getCallingPid(), Binder.getCallingUid(), null);
-        return uid;
     }
 
     private Ops getOpsLocked(int uid, String packageName, boolean edit) {
@@ -377,6 +382,10 @@
         if (ops == null) {
             return null;
         }
+        return getOpLocked(ops, code, edit);
+    }
+
+    private Op getOpLocked(Ops ops, int code, boolean edit) {
         Op op = ops.get(code);
         if (op == null) {
             if (!edit) {
diff --git a/services/java/com/android/server/EntropyMixer.java b/services/java/com/android/server/EntropyMixer.java
index 4632374..8c0d260 100644
--- a/services/java/com/android/server/EntropyMixer.java
+++ b/services/java/com/android/server/EntropyMixer.java
@@ -142,6 +142,7 @@
             out.println(SystemProperties.get("ro.bootloader"));
             out.println(SystemProperties.get("ro.hardware"));
             out.println(SystemProperties.get("ro.revision"));
+            out.println(SystemProperties.get("ro.build.fingerprint"));
             out.println(new Object().hashCode());
             out.println(System.currentTimeMillis());
             out.println(System.nanoTime());
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 37d7ce7..d121653 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -23,6 +23,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
+import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.INotificationManager;
 import android.app.ITransientNotification;
@@ -35,6 +36,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
@@ -62,21 +64,17 @@
 import android.util.Xml;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
-import android.widget.RemoteViews;
 import android.widget.Toast;
 
 import com.android.internal.statusbar.StatusBarNotification;
-import com.android.internal.util.FastXmlSerializer;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -156,6 +154,8 @@
     private ArrayList<NotificationRecord> mLights = new ArrayList<NotificationRecord>();
     private NotificationRecord mLedNotification;
 
+    private final AppOpsManager mAppOps;
+
     // Notification control database. For now just contains disabled packages.
     private AtomicFile mPolicyFile;
     private HashSet<String> mBlockedPackages = new HashSet<String>();
@@ -218,79 +218,35 @@
         }
     }
 
-    private void writeBlockDb() {
-        synchronized(mBlockedPackages) {
-            FileOutputStream outfile = null;
-            try {
-                outfile = mPolicyFile.startWrite();
-
-                XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(outfile, "utf-8");
-
-                out.startDocument(null, true);
-
-                out.startTag(null, TAG_BODY); {
-                    out.attribute(null, ATTR_VERSION, String.valueOf(DB_VERSION));
-                    out.startTag(null, TAG_BLOCKED_PKGS); {
-                        // write all known network policies
-                        for (String pkg : mBlockedPackages) {
-                            out.startTag(null, TAG_PACKAGE); {
-                                out.attribute(null, ATTR_NAME, pkg);
-                            } out.endTag(null, TAG_PACKAGE);
-                        }
-                    } out.endTag(null, TAG_BLOCKED_PKGS);
-                } out.endTag(null, TAG_BODY);
-
-                out.endDocument();
-
-                mPolicyFile.finishWrite(outfile);
-            } catch (IOException e) {
-                if (outfile != null) {
-                    mPolicyFile.failWrite(outfile);
-                }
-            }
-        }
-    }
-
-    public boolean areNotificationsEnabledForPackage(String pkg) {
+    /**
+     * Use this when you just want to know if notifications are OK for this package.
+     */
+    public boolean areNotificationsEnabledForPackage(String pkg, int uid) {
         checkCallerIsSystem();
-        return areNotificationsEnabledForPackageInt(pkg);
+        return (mAppOps.checkOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg)
+                == AppOpsManager.MODE_ALLOWED);
     }
 
-    // Unchecked. Not exposed via Binder, but can be called in the course of enqueue*().
-    private boolean areNotificationsEnabledForPackageInt(String pkg) {
-        final boolean enabled = !mBlockedPackages.contains(pkg);
-        if (DBG) {
-            Slog.v(TAG, "notifications are " + (enabled?"en":"dis") + "abled for " + pkg);
+    /** Use this when you actually want to post a notification or toast.
+     *
+     * Unchecked. Not exposed via Binder, but can be called in the course of enqueue*().
+     */
+    private boolean noteNotificationOp(String pkg, int uid) {
+        if (mAppOps.noteOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg)
+                != AppOpsManager.MODE_ALLOWED) {
+            Slog.v(TAG, "notifications are disabled by AppOps for " + pkg);
+            return false;
         }
-        return enabled;
+        return true;
     }
 
-    public void setNotificationsEnabledForPackage(String pkg, boolean enabled) {
+    public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
         checkCallerIsSystem();
-        if (DBG) {
+        if (true||DBG) {
             Slog.v(TAG, (enabled?"en":"dis") + "abling notifications for " + pkg);
         }
-        if (enabled) {
-            mBlockedPackages.remove(pkg);
-        } else {
-            mBlockedPackages.add(pkg);
-
-            // Now, cancel any outstanding notifications that are part of a just-disabled app
-            if (ENABLE_BLOCKED_NOTIFICATIONS) {
-                synchronized (mNotificationList) {
-                    final int N = mNotificationList.size();
-                    for (int i=0; i<N; i++) {
-                        final NotificationRecord r = mNotificationList.get(i);
-                        if (r.pkg.equals(pkg)) {
-                            cancelNotificationLocked(r, false);
-                        }
-                    }
-                }
-            }
-            // Don't bother canceling toasts, they'll go away soon enough.
-        }
-        writeBlockDb();
+        mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg,
+                enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
     }
 
 
@@ -322,6 +278,7 @@
     private static final class NotificationRecord
     {
         final String pkg;
+        final String basePkg;
         final String tag;
         final int id;
         final int uid;
@@ -331,10 +288,11 @@
         final int score;
         IBinder statusBarKey;
 
-        NotificationRecord(String pkg, String tag, int id, int uid, int initialPid,
+        NotificationRecord(String pkg, String basePkg, String tag, int id, int uid, int initialPid,
                 int userId, int score, Notification notification)
         {
             this.pkg = pkg;
+            this.basePkg = basePkg;
             this.tag = tag;
             this.id = id;
             this.uid = uid;
@@ -628,7 +586,9 @@
         mToastQueue = new ArrayList<ToastRecord>();
         mHandler = new WorkerHandler();
 
-        loadBlockDb();
+        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
+
+        importOldBlockDb();
 
         mStatusBar = statusBar;
         statusBar.setNotificationCallbacks(mNotificationCallbacks);
@@ -685,6 +645,28 @@
         observer.observe();
     }
 
+    /**
+     * Read the old XML-based app block database and import those blockages into the AppOps system.
+     */
+    private void importOldBlockDb() {
+        loadBlockDb();
+
+        PackageManager pm = mContext.getPackageManager();
+        for (String pkg : mBlockedPackages) {
+            PackageInfo info = null;
+            try {
+                info = pm.getPackageInfo(pkg, 0);
+                setNotificationsEnabledForPackage(pkg, info.applicationInfo.uid, false);
+            } catch (NameNotFoundException e) {
+                // forget you
+            }
+        }
+        mBlockedPackages.clear();
+        if (mPolicyFile != null) {
+            mPolicyFile.delete();
+        }
+    }
+
     void systemReady() {
         mAudioService = IAudioService.Stub.asInterface(
                 ServiceManager.getService(Context.AUDIO_SERVICE));
@@ -706,9 +688,11 @@
 
         final boolean isSystemToast = ("android".equals(pkg));
 
-        if (ENABLE_BLOCKED_TOASTS && !isSystemToast && !areNotificationsEnabledForPackageInt(pkg)) {
-            Slog.e(TAG, "Suppressing toast from package " + pkg + " by user request.");
-            return;
+        if (ENABLE_BLOCKED_TOASTS && !noteNotificationOp(pkg, Binder.getCallingUid())) {
+            if (!isSystemToast) {
+                Slog.e(TAG, "Suppressing toast from package " + pkg + " by user request.");
+                return;
+            }
         }
 
         synchronized (mToastQueue) {
@@ -898,10 +882,10 @@
 
     // Notifications
     // ============================================================================
-    public void enqueueNotificationWithTag(String pkg, String tag, int id, Notification notification,
-            int[] idOut, int userId)
+    public void enqueueNotificationWithTag(String pkg, String basePkg, String tag, int id,
+            Notification notification, int[] idOut, int userId)
     {
-        enqueueNotificationInternal(pkg, Binder.getCallingUid(), Binder.getCallingPid(),
+        enqueueNotificationInternal(pkg, basePkg, Binder.getCallingUid(), Binder.getCallingPid(),
                 tag, id, notification, idOut, userId);
     }
     
@@ -911,8 +895,8 @@
 
     // Not exposed via Binder; for system use only (otherwise malicious apps could spoof the
     // uid/pid of another application)
-    public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid,
-            String tag, int id, Notification notification, int[] idOut, int userId)
+    public void enqueueNotificationInternal(String pkg, String basePkg, int callingUid,
+            int callingPid, String tag, int id, Notification notification, int[] idOut, int userId)
     {
         if (DBG) {
             Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
@@ -982,9 +966,11 @@
         // 3. Apply local rules
 
         // blocked apps
-        if (ENABLE_BLOCKED_NOTIFICATIONS && !isSystemNotification && !areNotificationsEnabledForPackageInt(pkg)) {
-            score = JUNK_SCORE;
-            Slog.e(TAG, "Suppressing notification from package " + pkg + " by user request.");
+        if (ENABLE_BLOCKED_NOTIFICATIONS && !noteNotificationOp(pkg, callingUid)) {
+            if (!isSystemNotification) {
+                score = JUNK_SCORE;
+                Slog.e(TAG, "Suppressing notification from package " + pkg + " by user request.");
+            }
         }
 
         if (DBG) {
@@ -1000,7 +986,7 @@
         final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD);
 
         synchronized (mNotificationList) {
-            NotificationRecord r = new NotificationRecord(pkg, tag, id, 
+            NotificationRecord r = new NotificationRecord(pkg, basePkg, tag, id,
                     callingUid, callingPid, userId,
                     score,
                     notification);
@@ -1157,15 +1143,16 @@
                         // does not have the VIBRATE permission.
                         long identity = Binder.clearCallingIdentity();
                         try {
-                            mVibrator.vibrate(useDefaultVibrate ? mDefaultVibrationPattern
-                                                                : mFallbackVibrationPattern,
+                            mVibrator.vibrate(r.uid, r.basePkg,
+                                useDefaultVibrate ? mDefaultVibrationPattern
+                                    : mFallbackVibrationPattern,
                                 ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0: -1);
                         } finally {
                             Binder.restoreCallingIdentity(identity);
                         }
                     } else if (notification.vibrate.length > 1) {
                         // If you want your own vibration pattern, you need the VIBRATE permission
-                        mVibrator.vibrate(notification.vibrate,
+                        mVibrator.vibrate(r.uid, r.basePkg, notification.vibrate,
                             ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0: -1);
                     }
                 }
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 0e456f1..062be01 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -494,7 +494,7 @@
             if (Sandman.shouldStartDockApp(mContext, homeIntent)) {
                 try {
                     int result = ActivityManagerNative.getDefault().startActivityWithConfig(
-                            null, homeIntent, null, null, null, 0, 0,
+                            null, null, homeIntent, null, null, null, 0, 0,
                             mConfiguration, null, UserHandle.USER_CURRENT);
                     if (result >= ActivityManager.START_SUCCESS) {
                         dockAppStarted = true;
diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java
index 69379f1..9065525 100644
--- a/services/java/com/android/server/VibratorService.java
+++ b/services/java/com/android/server/VibratorService.java
@@ -178,12 +178,23 @@
         return doVibratorExists();
     }
 
-    public void vibrate(String packageName, long milliseconds, IBinder token) {
+    private void verifyIncomingUid(int uid) {
+        if (uid == Binder.getCallingUid()) {
+            return;
+        }
+        if (Binder.getCallingPid() == Process.myPid()) {
+            return;
+        }
+        mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+                Binder.getCallingPid(), Binder.getCallingUid(), null);
+    }
+
+    public void vibrate(int uid, String packageName, long milliseconds, IBinder token) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires VIBRATE permission");
         }
-        int uid = Binder.getCallingUid();
+        verifyIncomingUid(uid);
         // We're running in the system server so we cannot crash. Check for a
         // timeout of 0 or negative. This will ensure that a vibration has
         // either a timeout of > 0 or a non-null pattern.
@@ -219,12 +230,13 @@
         return true;
     }
 
-    public void vibratePattern(String packageName, long[] pattern, int repeat, IBinder token) {
+    public void vibratePattern(int uid, String packageName, long[] pattern, int repeat,
+            IBinder token) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires VIBRATE permission");
         }
-        int uid = Binder.getCallingUid();
+        verifyIncomingUid(uid);
         // so wakelock calls will succeed
         long identity = Binder.clearCallingIdentity();
         try {
@@ -454,7 +466,7 @@
         //synchronized (mInputDeviceVibrators) {
         //    return !mInputDeviceVibrators.isEmpty() || vibratorExists();
         //}
-        return vibratorExists();
+        return true || vibratorExists();
     }
 
     private void doVibratorOn(long millis, int uid) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ca60a93..252cae2 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -624,7 +624,6 @@
     /**
      * Thread-local storage used to carry caller permissions over through
      * indirect content-provider access.
-     * @see #ActivityManagerService.openContentUri()
      */
     private class Identity {
         public int pid;
@@ -831,18 +830,6 @@
             = new ArrayList<ProcessChangeItem>();
 
     /**
-     * Callback of last caller to {@link #requestPss}.
-     */
-    Runnable mRequestPssCallback;
-
-    /**
-     * Remaining processes for which we are waiting results from the last
-     * call to {@link #requestPss}.
-     */
-    final ArrayList<ProcessRecord> mRequestPssList
-            = new ArrayList<ProcessRecord>();
-    
-    /**
      * Runtime statistics collection thread.  This object's lock is used to
      * protect all related state.
      */
@@ -1231,7 +1218,7 @@
                     
                     try {
                         int[] outId = new int[1];
-                        inm.enqueueNotificationWithTag("android", null,
+                        inm.enqueueNotificationWithTag("android", "android", null,
                                 R.string.heavy_weight_notification,
                                 notification, outId, root.userId);
                     } catch (RuntimeException e) {
@@ -2309,7 +2296,7 @@
             if (app == null || app.instrumentationClass == null) {
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                 mMainStack.startActivityLocked(null, intent, null, aInfo,
-                        null, null, 0, 0, 0, 0, null, false, null);
+                        null, null, 0, 0, 0, null, 0, null, false, null);
             }
         }
 
@@ -2387,7 +2374,7 @@
                     intent.setComponent(new ComponentName(
                             ri.activityInfo.packageName, ri.activityInfo.name));
                     mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
-                            null, null, 0, 0, 0, 0, null, false, null);
+                            null, null, 0, 0, 0, null, 0, null, false, null);
                 }
             }
         }
@@ -2522,27 +2509,28 @@
         mPendingActivityLaunches.clear();
     }
 
-    public final int startActivity(IApplicationThread caller,
+    public final int startActivity(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags,
             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
-        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
+        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
+                resultWho, requestCode,
                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
     }
 
-    public final int startActivityAsUser(IApplicationThread caller,
+    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags,
             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
         enforceNotIsolatedCaller("startActivity");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivity", null);
-        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
+        return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
                 null, null, options, userId);
     }
 
-    public final WaitResult startActivityAndWait(IApplicationThread caller,
+    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) {
@@ -2550,20 +2538,20 @@
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityAndWait", null);
         WaitResult res = new WaitResult();
-        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
+        mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
                 res, null, options, UserHandle.getCallingUserId());
         return res;
     }
 
-    public final int startActivityWithConfig(IApplicationThread caller,
+    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, Configuration config,
             Bundle options, int userId) {
         enforceNotIsolatedCaller("startActivityWithConfig");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityWithConfig", null);
-        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
+        int ret = mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags,
                 null, null, null, config, options, userId);
         return ret;
@@ -2684,7 +2672,7 @@
             final long origId = Binder.clearCallingIdentity();
             int res = mMainStack.startActivityLocked(r.app.thread, intent,
                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
-                    resultWho, requestCode, -1, r.launchedFromUid, 0,
+                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
                     options, false, null);
             Binder.restoreCallingIdentity(origId);
 
@@ -2696,38 +2684,38 @@
         }
     }
 
-    final int startActivityInPackage(int uid,
+    final int startActivityInPackage(int uid, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
 
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityInPackage", null);
 
-        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
+        int ret = mMainStack.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags,
                 null, null, null, null, options, userId);
         return ret;
     }
 
-    public final int startActivities(IApplicationThread caller,
+    public final int startActivities(IApplicationThread caller, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
             int userId) {
         enforceNotIsolatedCaller("startActivities");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivity", null);
-        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
-                options, userId);
+        int ret = mMainStack.startActivities(caller, -1, callingPackage, intents,
+                resolvedTypes, resultTo, options, userId);
         return ret;
     }
 
-    final int startActivitiesInPackage(int uid,
+    final int startActivitiesInPackage(int uid, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
             Bundle options, int userId) {
 
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityInPackage", null);
-        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
-                options, userId);
+        int ret = mMainStack.startActivities(null, uid, callingPackage, intents, resolvedTypes,
+                resultTo, options, userId);
         return ret;
     }
 
@@ -6743,7 +6731,6 @@
 
     /**
      * Drop a content provider from a ProcessRecord's bookkeeping
-     * @param cpr
      */
     public void removeContentProvider(IBinder connection, boolean stable) {
         enforceNotIsolatedCaller("removeContentProvider");
@@ -12665,7 +12652,8 @@
                                 destIntent.getComponent(), 0, srec.userId);
                         int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
                                 null, aInfo, parent.appToken, null,
-                                0, -1, parent.launchedFromUid, 0, null, true, null);
+                                0, -1, parent.launchedFromUid, parent.launchedFromPackage,
+                                0, null, true, null);
                         foundParentInTask = res == ActivityManager.START_SUCCESS;
                     } catch (RemoteException e) {
                         foundParentInTask = false;
@@ -12687,6 +12675,14 @@
         return srec.launchedFromUid;
     }
 
+    public String getLaunchedFromPackage(IBinder activityToken) {
+        ActivityRecord srec = ActivityRecord.forToken(activityToken);
+        if (srec == null) {
+            return null;
+        }
+        return srec.launchedFromPackage;
+    }
+
     // =========================================================
     // LIFETIME MANAGEMENT
     // =========================================================
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 3af2287..ba2e47a 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -59,6 +59,7 @@
     final IApplicationToken.Stub appToken; // window manager token
     final ActivityInfo info; // all about me
     final int launchedFromUid; // always the uid who started the activity.
+    final String launchedFromPackage; // always the package who started the activity.
     final int userId;          // Which user is this running for?
     final Intent intent;    // the original intent that generated us
     final ComponentName realActivity;  // the intent component, or target of an alias.
@@ -135,6 +136,7 @@
         pw.print(prefix); pw.print("packageName="); pw.print(packageName);
                 pw.print(" processName="); pw.println(processName);
         pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
+                pw.print(" launchedFromPackage="); pw.println(launchedFromPackage);
                 pw.print(" userId="); pw.println(userId);
         pw.print(prefix); pw.print("app="); pw.println(app);
         pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
@@ -325,7 +327,7 @@
     }
 
     ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller,
-            int _launchedFromUid, Intent _intent, String _resolvedType,
+            int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
             ActivityInfo aInfo, Configuration _configuration,
             ActivityRecord _resultTo, String _resultWho, int _reqCode,
             boolean _componentSpecified) {
@@ -334,6 +336,7 @@
         appToken = new Token(this);
         info = aInfo;
         launchedFromUid = _launchedFromUid;
+        launchedFromPackage = _launchedFromPackage;
         userId = UserHandle.getUserId(aInfo.applicationInfo.uid);
         intent = _intent;
         shortComponentName = _intent.getComponent().flattenToShortString();
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index de9dda4..526b24f 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2483,7 +2483,7 @@
     final int startActivityLocked(IApplicationThread caller,
             Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
             String resultWho, int requestCode,
-            int callingPid, int callingUid, int startFlags, Bundle options,
+            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
             boolean componentSpecified, ActivityRecord[] outActivity) {
 
         int err = ActivityManager.START_SUCCESS;
@@ -2620,7 +2620,7 @@
             }
         }
 
-        ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
+        ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid, callingPackage,
                 intent, resolvedType, aInfo, mService.mConfiguration,
                 resultRecord, resultWho, requestCode, componentSpecified);
         if (outActivity != null) {
@@ -3095,7 +3095,7 @@
     }
 
     final int startActivityMayWait(IApplicationThread caller, int callingUid,
-            Intent intent, String resolvedType, IBinder resultTo,
+            String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
             Bundle options, int userId) {
@@ -3202,7 +3202,7 @@
             
             int res = startActivityLocked(caller, intent, resolvedType,
                     aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
-                    startFlags, options, componentSpecified, null);
+                    callingPackage, startFlags, options, componentSpecified, null);
             
             if (mConfigWillChange && mMainStack) {
                 // If the caller also wants to switch to a new configuration,
@@ -3253,7 +3253,7 @@
         }
     }
     
-    final int startActivities(IApplicationThread caller, int callingUid,
+    final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
             Bundle options, int userId) {
         if (intents == null) {
@@ -3316,7 +3316,7 @@
                         theseOptions = null;
                     }
                     int res = startActivityLocked(caller, intent, resolvedTypes[i],
-                            aInfo, resultTo, null, -1, callingPid, callingUid,
+                            aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
                             0, theseOptions, componentSpecified, outActivity);
                     if (res < 0) {
                         return res;
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 8ee303f..8ab71dd 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -246,11 +246,12 @@
                                 }
                                 allIntents[allIntents.length-1] = finalIntent;
                                 allResolvedTypes[allResolvedTypes.length-1] = resolvedType;
-                                owner.startActivitiesInPackage(uid, allIntents,
+                                owner.startActivitiesInPackage(uid, key.packageName, allIntents,
                                         allResolvedTypes, resultTo, options, userId);
                             } else {
-                                owner.startActivityInPackage(uid, finalIntent, resolvedType,
-                                        resultTo, resultWho, requestCode, 0, options, userId);
+                                owner.startActivityInPackage(uid, key.packageName, finalIntent,
+                                        resolvedType, resultTo, resultWho, requestCode, 0,
+                                        options, userId);
                             }
                         } catch (RuntimeException e) {
                             Slog.w(ActivityManagerService.TAG,
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 84e824a..b06c60a 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -369,8 +369,9 @@
                     }
                     try {
                         int[] outId = new int[1];
-                        nm.enqueueNotificationInternal(localPackageName, appUid, appPid,
-                                null, localForegroundId, localForegroundNoti, outId, userId);
+                        nm.enqueueNotificationInternal(localPackageName, localPackageName,
+                                appUid, appPid, null, localForegroundId, localForegroundNoti,
+                                outId, userId);
                     } catch (RuntimeException e) {
                         Slog.w(ActivityManagerService.TAG,
                                 "Error showing notification for service", e);
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index cbd2a0f..3ae652a 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -828,7 +828,7 @@
             final String packageName = mContext.getPackageName();
             final int[] idReceived = new int[1];
             mNotifManager.enqueueNotificationWithTag(
-                    packageName, tag, 0x0, builder.getNotification(), idReceived,
+                    packageName, packageName, tag, 0x0, builder.getNotification(), idReceived,
                     UserHandle.USER_OWNER);
             mActiveNotifs.add(tag);
         } catch (RemoteException e) {
@@ -863,7 +863,7 @@
         try {
             final String packageName = mContext.getPackageName();
             final int[] idReceived = new int[1];
-            mNotifManager.enqueueNotificationWithTag(packageName, tag,
+            mNotifManager.enqueueNotificationWithTag(packageName, packageName, tag,
                     0x0, builder.getNotification(), idReceived, UserHandle.USER_OWNER);
             mActiveNotifs.add(tag);
         } catch (RemoteException e) {
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index cb11be3..a335958 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -382,6 +382,16 @@
     }
 
     @Override
+    public int getOwningUid() {
+        return mSession.mUid;
+    }
+
+    @Override
+    public String getOwningPackage() {
+        return mAttrs.packageName;
+    }
+
+    @Override
     public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
         mHaveFrame = true;
 
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 47ce130..8b9f718 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -864,7 +864,8 @@
 
     private Future<String> expectEnqueueNotification() throws Exception {
         final FutureCapture<String> tag = new FutureCapture<String>();
-        mNotifManager.enqueueNotificationWithTag(isA(String.class), capture(tag.capture), anyInt(),
+        mNotifManager.enqueueNotificationWithTag(isA(String.class), isA(String.class),
+                capture(tag.capture), anyInt(),
                 isA(Notification.class), isA(int[].class), UserHandle.myUserId());
         return tag;
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6241a49..cd2a600 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -59,19 +59,19 @@
 public class TelephonyManager {
     private static final String TAG = "TelephonyManager";
 
-    private static Context sContext;
     private static ITelephonyRegistry sRegistry;
+    private final Context mContext;
 
     /** @hide */
     public TelephonyManager(Context context) {
-        if (sContext == null) {
-            Context appContext = context.getApplicationContext();
-            if (appContext != null) {
-                sContext = appContext;
-            } else {
-                sContext = context;
-            }
+        Context appContext = context.getApplicationContext();
+        if (appContext != null) {
+            mContext = appContext;
+        } else {
+            mContext = context;
+        }
 
+        if (sRegistry == null) {
             sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
                     "telephony.registry"));
         }
@@ -79,6 +79,7 @@
 
     /** @hide */
     private TelephonyManager() {
+        mContext = null;
     }
 
     private static TelephonyManager sInstance = new TelephonyManager();
@@ -276,7 +277,7 @@
      */
     public List<NeighboringCellInfo> getNeighboringCellInfo() {
         try {
-            return getITelephony().getNeighboringCellInfo();
+            return getITelephony().getNeighboringCellInfo(mContext.getBasePackageName());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -361,7 +362,7 @@
      * This function returns the type of the phone, depending
      * on the network mode.
      *
-     * @param network mode
+     * @param networkMode
      * @return Phone Type
      *
      * @hide
@@ -1199,7 +1200,7 @@
      *               LISTEN_ flags.
      */
     public void listen(PhoneStateListener listener, int events) {
-        String pkgForDebug = sContext != null ? sContext.getPackageName() : "<unknown>";
+        String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
         try {
             Boolean notifyNow = (getITelephony() != null);
             sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
@@ -1277,8 +1278,8 @@
      * @hide pending API review
      */
     public boolean isVoiceCapable() {
-        if (sContext == null) return true;
-        return sContext.getResources().getBoolean(
+        if (mContext == null) return true;
+        return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_voice_capable);
     }
 
@@ -1294,8 +1295,8 @@
      * @hide pending API review
      */
     public boolean isSmsCapable() {
-        if (sContext == null) return true;
-        return sContext.getResources().getBoolean(
+        if (mContext == null) return true;
+        return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_sms_capable);
     }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d5f0467..1449ab1 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -42,7 +42,7 @@
      * Place a call to the specified number.
      * @param number the number to be called.
      */
-    void call(String number);
+    void call(String callingPackage, String number);
 
     /**
      * If there is currently a call in progress, show the call screen.
@@ -218,7 +218,7 @@
     /**
      * Returns the neighboring cell information of the device.
      */
-    List<NeighboringCellInfo> getNeighboringCellInfo();
+    List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
 
      int getCallState();
      int getDataActivity();
diff --git a/telephony/java/com/android/internal/telephony/SmsRawData.aidl b/telephony/java/com/android/internal/telephony/SmsRawData.aidl
deleted file mode 100644
index b0b3e4f..0000000
--- a/telephony/java/com/android/internal/telephony/SmsRawData.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package com.android.internal.telephony;
-
-parcelable SmsRawData;
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 6b9f4c3..fbdd333 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -219,7 +219,7 @@
                             UserHandle.USER_CURRENT);
                 }
 
-                mResult = mAm.startActivityAndWait(null, mLaunchIntent, mimeType,
+                mResult = mAm.startActivityAndWait(null, null, mLaunchIntent, mimeType,
                         null, null, 0, mLaunchIntent.getFlags(), null, null, null,
                         UserHandle.USER_CURRENT);
             } catch (RemoteException e) {
diff --git a/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java b/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java
index b550957..397ef13 100644
--- a/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java
+++ b/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java
@@ -275,7 +275,7 @@
                             UserHandle.USER_CURRENT);
                 }
 
-                mAm.startActivityAndWait(null, mLaunchIntent, mimeType,
+                mAm.startActivityAndWait(null, null, mLaunchIntent, mimeType,
                         null, null, 0, mLaunchIntent.getFlags(), null, null, null,
                         UserHandle.USER_CURRENT_OR_SELF);
             } catch (RemoteException e) {
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsRS.java b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsRS.java
index 8cab9b8..d9d182c 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsRS.java
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsRS.java
@@ -20,8 +20,9 @@
 import android.renderscript.*;
 import android.util.Log;
 
+
 public class BallsRS {
-    public static final int PART_COUNT = 900;
+    public static final int PART_COUNT = 4000;
 
     public BallsRS() {
     }
@@ -30,11 +31,12 @@
     private RenderScriptGL mRS;
     private ScriptC_balls mScript;
     private ScriptC_ball_physics mPhysicsScript;
-    private ProgramFragment mPFLines;
     private ProgramFragment mPFPoints;
-    private ProgramVertex mPV;
     private ScriptField_Point mPoints;
     private ScriptField_VpConsts mVpConsts;
+    private ScriptField_BallGrid mGrid;
+    private ScriptField_Ball mBalls;
+    private Allocation mGridCache;
 
     void updateProjectionMatrices() {
         mVpConsts = new ScriptField_VpConsts(mRS, 1,
@@ -56,8 +58,8 @@
                     "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
                     "  pos.xy = ATTRIB_position;\n" +
                     "  gl_Position = UNI_MVP * pos;\n" +
-                    "  varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
-                    "  gl_PointSize = ATTRIB_size;\n" +
+                    "  varColor = ATTRIB_color;\n" +
+                    "  gl_PointSize = 12.0;\n" +
                     "}\n";
         sb.setShader(t);
         sb.addConstant(mVpConsts.getType());
@@ -84,22 +86,21 @@
         return builder.create();
     }
 
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-
-        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
+    private void createPF(int width, int height) {
+        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(mRS);
         pfb.setPointSpriteTexCoordinateReplacement(true);
         pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
                            ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
         pfb.setVaryingColor(true);
         mPFPoints = pfb.create();
+    }
 
-        pfb = new ProgramFragmentFixedFunction.Builder(rs);
-        pfb.setVaryingColor(true);
-        mPFLines = pfb.create();
+    public void init(RenderScriptGL rs, Resources res, int width, int height) {
+        mRS = rs;
+        mRes = res;
 
-        android.util.Log.e("rs", "Load texture");
+        createPF(width, height);
+
         mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
 
         mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
@@ -109,16 +110,22 @@
         smb.addIndexSetType(Mesh.Primitive.POINT);
         Mesh smP = smb.create();
 
-        mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics);
+        mGrid = ScriptField_BallGrid.create2D(mRS, (width + 99) / 100, (height + 99) / 100);
+        mGridCache = Allocation.createSized(mRS, Element.F32_2(mRS), PART_COUNT);
+        mBalls = new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
 
-        mScript = new ScriptC_balls(mRS, mRes, R.raw.balls);
+        mPhysicsScript = new ScriptC_ball_physics(mRS);
+        mPhysicsScript.set_gGridCache(mGridCache);
+        mPhysicsScript.set_gBalls(mBalls.getAllocation());
+
+        mScript = new ScriptC_balls(mRS);
         mScript.set_partMesh(smP);
         mScript.set_physics_script(mPhysicsScript);
         mScript.bind_point(mPoints);
-        mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
-        mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
+        mScript.bind_balls(mBalls);
+        mScript.set_gGrid(mGrid.getAllocation());
+        mScript.bind_gGridCache(mGridCache);
 
-        mScript.set_gPFLines(mPFLines);
         mScript.set_gPFPoints(mPFPoints);
         createProgramVertex();
 
@@ -126,6 +133,7 @@
 
         mPhysicsScript.set_gMinPos(new Float2(5, 5));
         mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5));
+        mPhysicsScript.set_gGrid(mGrid.getAllocation());
 
         mScript.invoke_initParts(width, height);
 
@@ -133,7 +141,7 @@
     }
 
     public void newTouchPosition(float x, float y, float pressure, int id) {
-        mPhysicsScript.invoke_touch(x, y, pressure, id);
+        mPhysicsScript.invoke_touch(x, y, pressure * mRS.getWidth() / 1280, id);
     }
 
     public void setAccel(float x, float y) {
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/ball_physics.rs b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/ball_physics.rs
index 8a3db6d..5b5d2e0 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/ball_physics.rs
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/ball_physics.rs
@@ -10,6 +10,13 @@
 
 static float2 touchPos[10];
 static float touchPressure[10];
+static const float gDT = 1.f / 30.f;
+
+rs_allocation gGrid;
+rs_allocation gGridCache;
+rs_allocation gBalls;
+
+float gScale = 1.f;
 
 void touch(float x, float y, float pressure, int id) {
     if (id >= 10) {
@@ -21,126 +28,128 @@
     touchPressure[id] = pressure;
 }
 
-void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint32_t x) {
-    float2 fv = {0, 0};
-    float2 pos = ballIn->position;
+void root(Ball_t *ball, uint32_t x) {
+    float2 fv = 0;
+    float pressure = 0;
+    float2 pos = ball->position;
+    int2 gridPos[9];
 
-    int arcID = -1;
-    float arcInvStr = 100000;
+    gridPos[0] = convert_int2((ball->position / 100.f) /*- 0.4999f*/);
+    gridPos[1] = (int2){gridPos[0].x - 1, gridPos[0].y - 1};
+    gridPos[2] = (int2){gridPos[0].x + 0, gridPos[0].y - 1};
+    gridPos[3] = (int2){gridPos[0].x + 1, gridPos[0].y - 1};
+    gridPos[4] = (int2){gridPos[0].x - 1, gridPos[0].y};
+    gridPos[5] = (int2){gridPos[0].x + 1, gridPos[0].y};
+    gridPos[6] = (int2){gridPos[0].x - 1, gridPos[0].y + 1};
+    gridPos[7] = (int2){gridPos[0].x + 0, gridPos[0].y + 1};
+    gridPos[8] = (int2){gridPos[0].x + 1, gridPos[0].y + 1};
 
-    const Ball_t * bPtr = rsGetElementAt(ctl->ain, 0);
-    for (uint32_t xin = 0; xin < ctl->dimX; xin++) {
-        float2 vec = bPtr[xin].position - pos;
-        float2 vec2 = vec * vec;
-        float len2 = vec2.x + vec2.y;
+    for (int gct=0; gct < 9; gct++) {
+        if ((gridPos[gct].x >= rsAllocationGetDimX(gGrid)) ||
+            (gridPos[gct].x < 0) ||
+            (gridPos[gct].y >= rsAllocationGetDimY(gGrid)) ||
+            (gridPos[gct].y < 0)) {
+            continue;
+        }
+        //rsDebug("grid ", gridPos[gct]);
+        const BallGrid_t *bg = (const BallGrid_t *)rsGetElementAt(gGrid, gridPos[gct].x, gridPos[gct].y);
 
-        if (len2 < 10000) {
-            //float minDist = ballIn->size + bPtr[xin].size;
-            float forceScale = ballIn->size * bPtr[xin].size;
-            forceScale *= forceScale;
+        for (int cidx = 0; cidx < bg->count; cidx++) {
+            float2 bcptr = rsGetElementAt_float2(gGridCache, bg->cacheIdx + cidx);
+            float2 vec = bcptr - pos;
+            float2 vec2 = vec * vec;
+            float len2 = vec2.x + vec2.y;
 
-            if (len2 > 16 /* (minDist*minDist)*/)  {
-                // Repulsion
-                float len = sqrt(len2);
-                fv -= (vec / (len * len * len)) * 20000.f * forceScale;
-            } else {
-                if (len2 < 1) {
-                    if (xin == x) {
-                        continue;
-                    }
-                    ballOut->delta = 0.f;
-                    ballOut->position = ballIn->position;
-                    if (xin > x) {
-                        ballOut->position.x += 1.f;
-                    } else {
-                        ballOut->position.x -= 1.f;
-                    }
-                    //ballOut->color.rgb = 1.f;
-                    //ballOut->arcID = -1;
-                    //ballOut->arcStr = 0;
-                    continue;
-                }
-                // Collision
-                float2 axis = normalize(vec);
-                float e1 = dot(axis, ballIn->delta);
-                float e2 = dot(axis, bPtr[xin].delta);
-                float e = (e1 - e2) * 0.45f;
-                if (e1 > 0) {
-                    fv -= axis * e;
-                } else {
-                    fv += axis * e;
-                }
+            if ((len2 < 10000.f) && (len2 > 0.f)) {
+                float t = native_powr(len2, 1.5f) + 16.0f;
+                float2 pfv = (vec / t) * 16000.f;
+                pressure += length(pfv);
+                fv -= pfv;
             }
         }
     }
 
-    fv /= ballIn->size * ballIn->size * ballIn->size;
-    fv -= gGravityVector * 4.f;
-    fv *= ctl->dt;
+    //fv /= ball->size * ball->size * ball->size;
+    fv -= gGravityVector * 4.f * gScale;
+    fv *= gDT;
 
     for (int i=0; i < 10; i++) {
         if (touchPressure[i] > 0.1f) {
-            float2 vec = touchPos[i] - ballIn->position;
+            float2 vec = touchPos[i] - ball->position;
             float2 vec2 = vec * vec;
             float len2 = max(2.f, vec2.x + vec2.y);
-            fv -= (vec / len2) * touchPressure[i] * 300.f;
+            float2 pfv = (vec / len2) * touchPressure[i] * 500.f * gScale;
+            pressure += length(pfv);
+            fv -= pfv;
         }
     }
 
-    ballOut->delta = (ballIn->delta * (1.f - 0.004f)) + fv;
-    ballOut->position = ballIn->position + (ballOut->delta * ctl->dt);
+    ball->delta = (ball->delta * (1.f - 0.008f)) + fv;
+    ball->position = ball->position + (ball->delta * gDT);
 
-    const float wallForce = 400.f;
-    if (ballOut->position.x > (gMaxPos.x - 20.f)) {
-        float d = gMaxPos.x - ballOut->position.x;
+    const float wallForce = 400.f * gScale;
+    if (ball->position.x > (gMaxPos.x - 20.f)) {
+        float d = gMaxPos.x - ball->position.x;
         if (d < 0.f) {
-            if (ballOut->delta.x > 0) {
-                ballOut->delta.x *= -0.7f;
+            if (ball->delta.x > 0) {
+                ball->delta.x *= -0.7f;
             }
-            ballOut->position.x = gMaxPos.x;
+            ball->position.x = gMaxPos.x - 1.f;
         } else {
-            ballOut->delta.x -= min(wallForce / (d * d), 10.f);
+            ball->delta.x -= min(wallForce / (d * d), 10.f);
         }
     }
 
-    if (ballOut->position.x < (gMinPos.x + 20.f)) {
-        float d = ballOut->position.x - gMinPos.x;
+    if (ball->position.x < (gMinPos.x + 20.f)) {
+        float d = ball->position.x - gMinPos.x;
         if (d < 0.f) {
-            if (ballOut->delta.x < 0) {
-                ballOut->delta.x *= -0.7f;
+            if (ball->delta.x < 0) {
+                ball->delta.x *= -0.7f;
             }
-            ballOut->position.x = gMinPos.x + 1.f;
+            ball->position.x = gMinPos.x + 1.f;
         } else {
-            ballOut->delta.x += min(wallForce / (d * d), 10.f);
+            ball->delta.x += min(wallForce / (d * d), 10.f);
         }
     }
 
-    if (ballOut->position.y > (gMaxPos.y - 20.f)) {
-        float d = gMaxPos.y - ballOut->position.y;
+    if (ball->position.y > (gMaxPos.y - 20.f)) {
+        float d = gMaxPos.y - ball->position.y;
         if (d < 0.f) {
-            if (ballOut->delta.y > 0) {
-                ballOut->delta.y *= -0.7f;
+            if (ball->delta.y > 0) {
+                ball->delta.y *= -0.7f;
             }
-            ballOut->position.y = gMaxPos.y;
+            ball->position.y = gMaxPos.y - 1.f;
         } else {
-            ballOut->delta.y -= min(wallForce / (d * d), 10.f);
+            ball->delta.y -= min(wallForce / (d * d), 10.f);
         }
     }
 
-    if (ballOut->position.y < (gMinPos.y + 20.f)) {
-        float d = ballOut->position.y - gMinPos.y;
+    if (ball->position.y < (gMinPos.y + 20.f)) {
+        float d = ball->position.y - gMinPos.y;
         if (d < 0.f) {
-            if (ballOut->delta.y < 0) {
-                ballOut->delta.y *= -0.7f;
+            if (ball->delta.y < 0) {
+                ball->delta.y *= -0.7f;
             }
-            ballOut->position.y = gMinPos.y + 1.f;
+            ball->position.y = gMinPos.y + 1.f;
         } else {
-            ballOut->delta.y += min(wallForce / (d * d * d), 10.f);
+            ball->delta.y += min(wallForce / (d * d * d), 10.f);
         }
     }
 
-    ballOut->size = ballIn->size;
+    // low pressure ~500, high ~2500
+    pressure = max(pressure - 400.f, 0.f);
+    ball->pressure = pressure;
 
-    //rsDebug("physics pos out", ballOut->position);
+    //rsDebug("p ", pressure);
+
+    float4 color = 1.f;
+    color.r = pow(pressure, 0.25f) / 12.f;
+    color.b = 1.f - color.r;
+    color.g = sin(pressure / 1500.f * 3.14f);
+    color.rgb = max(color.rgb, (float3)0);
+    color.rgb = normalize(color.rgb);
+    ball->color = rsPackColorTo8888(color);
+
+    //rsDebug("physics pos out", ball->position);
 }
 
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rs b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rs
index dcdd586..9be9f38 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rs
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rs
@@ -8,12 +8,15 @@
 #pragma stateStore(parent)
 
 rs_program_fragment gPFPoints;
-rs_program_fragment gPFLines;
 rs_mesh partMesh;
 
+rs_allocation gGrid;
+BallGrid_t *unused1;
+float2 *gGridCache;
+
 typedef struct __attribute__((packed, aligned(4))) Point {
     float2 position;
-    float size;
+    uchar4 color;
 } Point_t;
 Point_t *point;
 
@@ -24,58 +27,78 @@
 
 rs_script physics_script;
 
-Ball_t *balls1;
-Ball_t *balls2;
-
-static int frame = 0;
 
 void initParts(int w, int h)
 {
-    uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls1));
+    uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls));
 
     for (uint32_t ct=0; ct < dimX; ct++) {
-        balls1[ct].position.x = rsRand(0.f, (float)w);
-        balls1[ct].position.y = rsRand(0.f, (float)h);
-        balls1[ct].delta.x = 0.f;
-        balls1[ct].delta.y = 0.f;
-        balls1[ct].size = 1.f;
-
-        float r = rsRand(100.f);
-        if (r > 90.f) {
-            balls1[ct].size += pow(10.f, rsRand(0.f, 2.f)) * 0.07f;
-        }
+        balls[ct].position.x = rsRand(0.f, (float)w);
+        balls[ct].position.y = rsRand(0.f, (float)h);
+        balls[ct].delta.x = 0.f;
+        balls[ct].delta.y = 0.f;
     }
 }
 
-
-
 int root() {
     rsgClearColor(0.f, 0.f, 0.f, 1.f);
 
-    BallControl_t bc;
-    Ball_t *bout;
+    int2 gridDims = (int2){ rsAllocationGetDimX(gGrid),
+                            rsAllocationGetDimY(gGrid) };
 
-    if (frame & 1) {
-        bc.ain = rsGetAllocation(balls2);
-        bc.aout = rsGetAllocation(balls1);
-        bout = balls1;
-    } else {
-        bc.ain = rsGetAllocation(balls1);
-        bc.aout = rsGetAllocation(balls2);
-        bout = balls2;
+    rs_allocation ain = rsGetAllocation(balls);
+    int32_t dimX = rsAllocationGetDimX(ain);
+
+    // Binning
+    // Clear the particle list
+    for (uint32_t ct=0; ct < dimX; ct++) {
+        balls[ct].next = -1;
     }
 
-    bc.dimX = rsAllocationGetDimX(bc.ain);
-    bc.dt = 1.f / 30.f;
-
-    rsForEach(physics_script, bc.ain, bc.aout, &bc, sizeof(bc));
-
-    for (uint32_t ct=0; ct < bc.dimX; ct++) {
-        point[ct].position = bout[ct].position;
-        point[ct].size = 6.f /*+ bout[ct].color.g * 6.f*/ * bout[ct].size;
+    // Clear the grid
+    for (uint32_t y=0; y < gridDims.y; y++) {
+        for (uint32_t x=0; x < gridDims.x; x++) {
+            BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, x, y);
+            bg->count = 0;
+            bg->idx = -1;
+        }
     }
 
-    frame++;
+    // Create the particle list per grid
+    for (uint32_t ct=0; ct < dimX; ct++) {
+        int2 p = convert_int2(balls[ct].position / 100.f);
+        p.x = rsClamp(p.x, 0, (int)(gridDims.x-1));
+        p.y = rsClamp(p.y, 0, (int)(gridDims.y-1));
+        BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, p.x, p.y);
+        bg->count ++;
+        balls[ct].next = bg->idx;
+        bg->idx = ct;
+    }
+
+    // Create the sorted grid cache
+    uint32_t gridIdx = 0;
+    for (uint32_t y=0; y < gridDims.y; y++) {
+        for (uint32_t x=0; x < gridDims.x; x++) {
+            BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, x, y);
+            bg->cacheIdx = gridIdx;
+
+            int idx = bg->idx;
+            while (idx >= 0) {
+                const Ball_t * bPtr = &balls[idx];
+                gGridCache[gridIdx++] = bPtr->position;
+                idx = bPtr->next;
+            }
+        }
+    }
+
+
+    rsForEach(physics_script, ain, ain);
+
+    for (uint32_t ct=0; ct < dimX; ct++) {
+        point[ct].position = balls[ct].position;
+        point[ct].color = balls[ct].color;
+    }
+
     rsgBindProgramFragment(gPFPoints);
     rsgDrawMesh(partMesh);
     return 1;
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rsh b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rsh
index fc886f9..ebe23f8 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rsh
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rsh
@@ -2,17 +2,18 @@
 typedef struct __attribute__((packed, aligned(4))) Ball {
     float2 delta;
     float2 position;
-    //float3 color;
-    float size;
+    uchar4 color;
+    float pressure;
+    //float size;
+    int32_t next;
     //int arcID;
     //float arcStr;
 } Ball_t;
 Ball_t *balls;
 
 
-typedef struct BallControl {
-    uint32_t dimX;
-    rs_allocation ain;
-    rs_allocation aout;
-    float dt;
-} BallControl_t;
+typedef struct BallGrid {
+    int32_t idx;
+    int32_t count;
+    int32_t cacheIdx;
+} BallGrid_t;
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index ec39aab..4345098 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -796,6 +796,7 @@
                     INotificationManager directLine = mNM.getService();
                     directLine.enqueueNotificationWithTag(
                             getPackageName(),
+                            getPackageName(),
                             null, 
                             100, 
                             n,
@@ -821,7 +822,8 @@
                     INotificationManager directLine = mNM.getService();
                     directLine.enqueueNotificationWithTag(
                             getPackageName(),
-                            null, 
+                            getPackageName(),
+                            null,
                             200, 
                             n,
                             idOut,
@@ -846,7 +848,8 @@
                     INotificationManager directLine = mNM.getService();
                     directLine.enqueueNotificationWithTag(
                             getPackageName(),
-                            null, 
+                            getPackageName(),
+                            null,
                             1, 
                             n,
                             idOut,
diff --git a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
index 2416828..90b6abc 100644
--- a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
@@ -20,6 +20,7 @@
 
 import android.os.Binder;
 import android.os.IVibratorService;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -46,7 +47,7 @@
      */
     public void testVibrate() throws RemoteException {
         try {
-            mVibratorService.vibrate(null, 2000, new Binder());
+            mVibratorService.vibrate(Process.myUid(), null, 2000, new Binder());
             fail("vibrate did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected
@@ -62,7 +63,7 @@
      */
     public void testVibratePattern() throws RemoteException {
         try {
-            mVibratorService.vibratePattern(null, new long[] {0}, 0, new Binder());
+            mVibratorService.vibratePattern(Process.myUid(), null, new long[] {0}, 0, new Binder());
             fail("vibratePattern did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected