am 6fe87a56: am 68ffcf88: Merge "Teach receivers, activities, providers, and services app ops." into mnc-dev

* commit '6fe87a565be345c9455f610bbf26d5eaee593683':
  Teach receivers, activities, providers, and services app ops.
diff --git a/api/current.txt b/api/current.txt
index df66811..3304317 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3855,6 +3855,8 @@
     method public void finishOp(java.lang.String, int, java.lang.String);
     method public int noteOp(java.lang.String, int, java.lang.String);
     method public int noteOpNoThrow(java.lang.String, int, java.lang.String);
+    method public int noteProxyOp(java.lang.String, java.lang.String);
+    method public int noteProxyOpNoThrow(java.lang.String, java.lang.String);
     method public static java.lang.String permissionToOp(java.lang.String);
     method public int startOp(java.lang.String, int, java.lang.String);
     method public int startOpNoThrow(java.lang.String, int, java.lang.String);
diff --git a/api/system-current.txt b/api/system-current.txt
index f6301e8..e3f003c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3964,6 +3964,8 @@
     method public void finishOp(java.lang.String, int, java.lang.String);
     method public int noteOp(java.lang.String, int, java.lang.String);
     method public int noteOpNoThrow(java.lang.String, int, java.lang.String);
+    method public int noteProxyOp(java.lang.String, java.lang.String);
+    method public int noteProxyOpNoThrow(java.lang.String, java.lang.String);
     method public static java.lang.String permissionToOp(java.lang.String);
     method public int startOp(java.lang.String, int, java.lang.String);
     method public int startOpNoThrow(java.lang.String, int, java.lang.String);
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 2ed4b51..8797b13 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -770,7 +770,7 @@
             return;
         }
         System.out.println("Starting service: " + intent);
-        ComponentName cn = mAm.startService(null, intent, intent.getType(), mUserId);
+        ComponentName cn = mAm.startService(null, intent, intent.getType(), null, mUserId);
         if (cn == null) {
             System.err.println("Error: Not found; no service started.");
         } else if (cn.getPackageName().equals("!")) {
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 2bb4e76..cc93ac9 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -921,8 +921,9 @@
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
             Intent service = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
+            String callingPackage = data.readString();
             int userId = data.readInt();
-            ComponentName cn = startService(app, service, resolvedType, userId);
+            ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
             reply.writeNoException();
             ComponentName.writeToParcel(cn, reply);
             return true;
@@ -976,9 +977,11 @@
             String resolvedType = data.readString();
             b = data.readStrongBinder();
             int fl = data.readInt();
+            String callingPackage = data.readString();
             int userId = data.readInt();
             IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
-            int res = bindService(app, token, service, resolvedType, conn, fl, userId);
+            int res = bindService(app, token, service, resolvedType, conn, fl,
+                    callingPackage, userId);
             reply.writeNoException();
             reply.writeInt(res);
             return true;
@@ -1568,7 +1571,8 @@
             data.enforceInterface(IActivityManager.descriptor);
             Intent service = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
-            IBinder binder = peekService(service, resolvedType);
+            String callingPackage = data.readString();
+            IBinder binder = peekService(service, resolvedType, callingPackage);
             reply.writeNoException();
             reply.writeStrongBinder(binder);
             return true;
@@ -3638,7 +3642,7 @@
     }
 
     public ComponentName startService(IApplicationThread caller, Intent service,
-            String resolvedType, int userId) throws RemoteException
+            String resolvedType, String callingPackage, int userId) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -3646,6 +3650,7 @@
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
         service.writeToParcel(data, 0);
         data.writeString(resolvedType);
+        data.writeString(callingPackage);
         data.writeInt(userId);
         mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
         reply.readException();
@@ -3708,7 +3713,7 @@
     }
     public int bindService(IApplicationThread caller, IBinder token,
             Intent service, String resolvedType, IServiceConnection connection,
-            int flags, int userId) throws RemoteException {
+            int flags,  String callingPackage, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -3718,6 +3723,7 @@
         data.writeString(resolvedType);
         data.writeStrongBinder(connection.asBinder());
         data.writeInt(flags);
+        data.writeString(callingPackage);
         data.writeInt(userId);
         mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
         reply.readException();
@@ -3783,12 +3789,14 @@
         reply.recycle();
     }
 
-    public IBinder peekService(Intent service, String resolvedType) throws RemoteException {
+    public IBinder peekService(Intent service, String resolvedType, String callingPackage)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         service.writeToParcel(data, 0);
         data.writeString(resolvedType);
+        data.writeString(callingPackage);
         mRemote.transact(PEEK_SERVICE_TRANSACTION, data, reply, 0);
         reply.readException();
         IBinder binder = reply.readStrongBinder();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 9faadd3..bf3bfae 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1082,13 +1082,18 @@
         private final long mTime;
         private final long mRejectTime;
         private final int mDuration;
+        private final int mProxyUid;
+        private final String mProxyPackageName;
 
-        public OpEntry(int op, int mode, long time, long rejectTime, int duration) {
+        public OpEntry(int op, int mode, long time, long rejectTime, int duration,
+                int proxyUid, String proxyPackage) {
             mOp = op;
             mMode = mode;
             mTime = time;
             mRejectTime = rejectTime;
             mDuration = duration;
+            mProxyUid = proxyUid;
+            mProxyPackageName = proxyPackage;
         }
 
         public int getOp() {
@@ -1115,6 +1120,14 @@
             return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
         }
 
+        public int getProxyUid() {
+            return  mProxyUid;
+        }
+
+        public String getProxyPackageName() {
+            return mProxyPackageName;
+        }
+
         @Override
         public int describeContents() {
             return 0;
@@ -1127,6 +1140,8 @@
             dest.writeLong(mTime);
             dest.writeLong(mRejectTime);
             dest.writeInt(mDuration);
+            dest.writeInt(mProxyUid);
+            dest.writeString(mProxyPackageName);
         }
 
         OpEntry(Parcel source) {
@@ -1135,6 +1150,8 @@
             mTime = source.readLong();
             mRejectTime = source.readLong();
             mDuration = source.readInt();
+            mProxyUid = source.readInt();
+            mProxyPackageName = source.readString();
         }
 
         public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
@@ -1379,6 +1396,33 @@
     }
 
     /**
+     * Make note of an application performing an operation on behalf of another
+     * application when handling an IPC. Note that you must pass the package name
+     * of the application that is being proxied while its UID will be inferred from
+     * the IPC state; this function will verify that the calling uid and proxied
+     * package name match, and if not, return {@link #MODE_IGNORED}. If this call
+     * succeeds, the last execution time of the operation for the proxied app and
+     * your app will be updated to the current time.
+     * @param op The operation to note.  One of the OPSTR_* constants.
+     * @param proxiedPackageName The name of the application calling into the proxy application.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @throws SecurityException If the app has been configured to crash on this op.
+     */
+    public int noteProxyOp(String op, String proxiedPackageName) {
+        return noteProxyOp(strOpToOp(op), proxiedPackageName);
+    }
+
+    /**
+     * Like {@link #noteProxyOp(String, String)} but instead
+     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
+     */
+    public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
+        return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
+    }
+
+    /**
      * Report that an application has started executing a long-running operation.  Note that you
      * must pass in both the uid and name of the application to be checked; this function will
      * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
@@ -1455,7 +1499,7 @@
             return mService.checkOperation(op, uid, packageName);
         } catch (RemoteException e) {
         }
-        return MODE_IGNORED;
+        return MODE_ERRORED;
     }
 
     /**
@@ -1501,7 +1545,7 @@
             return mService.checkAudioOperation(op, stream, uid, packageName);
         } catch (RemoteException e) {
         }
-        return MODE_IGNORED;
+        return MODE_ERRORED;
     }
 
     /**
@@ -1532,6 +1576,49 @@
     }
 
     /**
+     * Make note of an application performing an operation on behalf of another
+     * application when handling an IPC. Note that you must pass the package name
+     * of the application that is being proxied while its UID will be inferred from
+     * the IPC state; this function will verify that the calling uid and proxied
+     * package name match, and if not, return {@link #MODE_IGNORED}. If this call
+     * succeeds, the last execution time of the operation for the proxied app and
+     * your app will be updated to the current time.
+     * @param op The operation to note. One of the OPSTR_* constants.
+     * @param proxiedPackageName The name of the application calling into the proxy application.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @throws SecurityException If the proxy or proxied app has been configured to
+     * crash on this op.
+     *
+     * @hide
+     */
+    public int noteProxyOp(int op, String proxiedPackageName) {
+        int mode = noteProxyOpNoThrow(op, proxiedPackageName);
+        if (mode == MODE_ERRORED) {
+            throw new SecurityException("Proxy package " + mContext.getOpPackageName()
+                    + " from uid " + Process.myUid() + " or calling package "
+                    + proxiedPackageName + " from uid " + Binder.getCallingUid()
+                    + " not allowed to perform " + sOpNames[op]);
+        }
+        return mode;
+    }
+
+    /**
+     * Like {@link #noteProxyOp(int, String)} but instead
+     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
+     * @hide
+     */
+    public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
+        try {
+            return mService.noteProxyOperation(op, mContext.getOpPackageName(),
+                    Binder.getCallingUid(), proxiedPackageName);
+        } catch (RemoteException e) {
+        }
+        return MODE_ERRORED;
+    }
+
+    /**
      * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
      * returns {@link #MODE_ERRORED}.
      * @hide
@@ -1541,7 +1628,7 @@
             return mService.noteOperation(op, uid, packageName);
         } catch (RemoteException e) {
         }
-        return MODE_IGNORED;
+        return MODE_ERRORED;
     }
 
     /** @hide */
@@ -1603,7 +1690,7 @@
             return mService.startOperation(getToken(mService), op, uid, packageName);
         } catch (RemoteException e) {
         }
-        return MODE_IGNORED;
+        return MODE_ERRORED;
     }
 
     /** @hide */
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 0420fb6..6639486 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1202,8 +1202,8 @@
             validateServiceIntent(service);
             service.prepareToLeaveProcess();
             ComponentName cn = ActivityManagerNative.getDefault().startService(
-                mMainThread.getApplicationThread(), service,
-                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
+                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
+                            getContentResolver()), getOpPackageName(), user.getIdentifier());
             if (cn != null) {
                 if (cn.getPackageName().equals("!")) {
                     throw new SecurityException(
@@ -1279,9 +1279,9 @@
             }
             service.prepareToLeaveProcess();
             int res = ActivityManagerNative.getDefault().bindService(
-                mMainThread.getApplicationThread(), getActivityToken(),
-                service, service.resolveTypeIfNeeded(getContentResolver()),
-                sd, flags, user.getIdentifier());
+                mMainThread.getApplicationThread(), getActivityToken(), service,
+                service.resolveTypeIfNeeded(getContentResolver()),
+                sd, flags, getOpPackageName(), user.getIdentifier());
             if (res < 0) {
                 throw new SecurityException(
                         "Not allowed to bind to service " + service);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 1423e4b..acce81c 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -160,16 +160,16 @@
     public PendingIntent getRunningServiceControlPanel(ComponentName service)
             throws RemoteException;
     public ComponentName startService(IApplicationThread caller, Intent service,
-            String resolvedType, int userId) throws RemoteException;
+            String resolvedType, String callingPackage, int userId) throws RemoteException;
     public int stopService(IApplicationThread caller, Intent service,
             String resolvedType, int userId) throws RemoteException;
     public boolean stopServiceToken(ComponentName className, IBinder token,
             int startId) throws RemoteException;
     public void setServiceForeground(ComponentName className, IBinder token,
             int id, Notification notification, boolean keepNotification) throws RemoteException;
-    public int bindService(IApplicationThread caller, IBinder token,
-            Intent service, String resolvedType,
-            IServiceConnection connection, int flags, int userId) throws RemoteException;
+    public int bindService(IApplicationThread caller, IBinder token, Intent service,
+            String resolvedType, IServiceConnection connection, int flags,
+            String callingPackage, int userId) throws RemoteException;
     public boolean unbindService(IServiceConnection connection) throws RemoteException;
     public void publishService(IBinder token,
             Intent intent, IBinder service) throws RemoteException;
@@ -178,7 +178,8 @@
     /* oneway */
     public void serviceDoneExecuting(IBinder token, int type, int startId,
             int res) throws RemoteException;
-    public IBinder peekService(Intent service, String resolvedType) throws RemoteException;
+    public IBinder peekService(Intent service, String resolvedType, String callingPackage)
+            throws RemoteException;
 
     public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode)
             throws RemoteException;
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index af74e73..2260d7e 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -524,7 +524,7 @@
         try {
             service.prepareToLeaveProcess();
             binder = am.peekService(service, service.resolveTypeIfNeeded(
-                    myContext.getContentResolver()));
+                    myContext.getContentResolver()), myContext.getOpPackageName());
         } catch (RemoteException e) {
         }
         return binder;
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index d4c4437..3cc7684 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -475,18 +475,38 @@
         private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken)
                 throws SecurityException {
             enforceReadPermissionInner(uri, callerToken);
-            if (mReadOp != AppOpsManager.OP_NONE) {
-                return mAppOpsManager.noteOp(mReadOp, Binder.getCallingUid(), callingPkg);
+
+            final int permOp = AppOpsManager.permissionToOpCode(mReadPermission);
+            if (permOp != AppOpsManager.OP_NONE) {
+                final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg);
+                if (mode != AppOpsManager.MODE_ALLOWED) {
+                    return mode;
+                }
             }
+
+            if (mReadOp != AppOpsManager.OP_NONE) {
+                return mAppOpsManager.noteProxyOp(mReadOp, callingPkg);
+            }
+
             return AppOpsManager.MODE_ALLOWED;
         }
 
         private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken)
                 throws SecurityException {
             enforceWritePermissionInner(uri, callerToken);
-            if (mWriteOp != AppOpsManager.OP_NONE) {
-                return mAppOpsManager.noteOp(mWriteOp, Binder.getCallingUid(), callingPkg);
+
+            final int permOp = AppOpsManager.permissionToOpCode(mWritePermission);
+            if (permOp != AppOpsManager.OP_NONE) {
+                final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg);
+                if (mode != AppOpsManager.MODE_ALLOWED) {
+                    return mode;
+                }
             }
+
+            if (mWriteOp != AppOpsManager.OP_NONE) {
+                return mAppOpsManager.noteProxyOp(mWriteOp, callingPkg);
+            }
+
             return AppOpsManager.MODE_ALLOWED;
         }
     }
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 86c1b2f..201a124aa 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -25,6 +25,8 @@
     // be kept in sync with frameworks/native/include/binder/IAppOpsService.h
     int checkOperation(int code, int uid, String packageName);
     int noteOperation(int code, int uid, String packageName);
+    int noteProxyOperation(int code, String proxyPackageName,
+            int callingUid, String callingPackageName);
     int startOperation(IBinder token, int code, int uid, String packageName);
     void finishOperation(IBinder token, int code, int uid, String packageName);
     void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 79c66b9..f0fc399 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -116,6 +116,8 @@
     public final static class Op {
         public final int uid;
         public final String packageName;
+        public int proxyUid = -1;
+        public String proxyPackageName;
         public final int op;
         public int mode;
         public int duration;
@@ -289,7 +291,8 @@
             for (int j=0; j<pkgOps.size(); j++) {
                 Op curOp = pkgOps.valueAt(j);
                 resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                        curOp.rejectTime, curOp.duration));
+                        curOp.rejectTime, curOp.duration, curOp.proxyUid,
+                        curOp.proxyPackageName));
             }
         } else {
             for (int j=0; j<ops.length; j++) {
@@ -299,7 +302,8 @@
                         resOps = new ArrayList<AppOpsManager.OpEntry>();
                     }
                     resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                            curOp.rejectTime, curOp.duration));
+                            curOp.rejectTime, curOp.duration, curOp.proxyUid,
+                            curOp.proxyPackageName));
                 }
             }
         }
@@ -659,9 +663,28 @@
     }
 
     @Override
+    public int noteProxyOperation(int code, String proxyPackageName,
+            int proxiedUid, String proxiedPackageName) {
+        verifyIncomingOp(code);
+        final int proxyMode = noteOperationUnchecked(code, Binder.getCallingUid(),
+                proxyPackageName, -1, null);
+        if (proxyMode != AppOpsManager.MODE_ALLOWED || Binder.getCallingUid() == proxiedUid) {
+            return proxyMode;
+        }
+        return noteOperationUnchecked(code, proxiedUid, proxiedPackageName,
+                Binder.getCallingUid(), proxyPackageName);
+
+    }
+
+    @Override
     public int noteOperation(int code, int uid, String packageName) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
+        return noteOperationUnchecked(code, uid, packageName, 0, null);
+    }
+
+    private int noteOperationUnchecked(int code, int uid, String packageName,
+            int proxyUid, String proxyPackageName) {
         synchronized (this) {
             Ops ops = getOpsLocked(uid, packageName, true);
             if (ops == null) {
@@ -690,6 +713,8 @@
                     + " package " + packageName);
             op.time = System.currentTimeMillis();
             op.rejectTime = 0;
+            op.proxyUid = proxyUid;
+            op.proxyPackageName = proxyPackageName;
             return AppOpsManager.MODE_ALLOWED;
         }
     }
@@ -1051,6 +1076,14 @@
                 if (dur != null) {
                     op.duration = Integer.parseInt(dur);
                 }
+                String proxyUid = parser.getAttributeValue(null, "pu");
+                if (proxyUid != null) {
+                    op.proxyUid = Integer.parseInt(proxyUid);
+                }
+                String proxyPackageName = parser.getAttributeValue(null, "pp");
+                if (proxyPackageName != null) {
+                    op.proxyPackageName = proxyPackageName;
+                }
                 HashMap<String, Ops> pkgOps = mUidOps.get(uid);
                 if (pkgOps == null) {
                     pkgOps = new HashMap<String, Ops>();
@@ -1132,6 +1165,14 @@
                             if (dur != 0) {
                                 out.attribute(null, "d", Integer.toString(dur));
                             }
+                            int proxyUid = op.getProxyUid();
+                            if (proxyUid != -1) {
+                                out.attribute(null, "pu", Integer.toString(proxyUid));
+                            }
+                            String proxyPackageName = op.getProxyPackageName();
+                            if (proxyPackageName != null) {
+                                out.attribute(null, "pp", proxyPackageName);
+                            }
                             out.endTag(null, "op");
                         }
                         out.endTag(null, "uid");
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 333db5d..899139f 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -29,6 +29,7 @@
 import java.util.Set;
 
 import android.app.ActivityThread;
+import android.app.AppOpsManager;
 import android.os.Build;
 import android.os.DeadObjectException;
 import android.os.Handler;
@@ -302,8 +303,8 @@
         return getServiceMap(callingUser).mServicesByName;
     }
 
-    ComponentName startServiceLocked(IApplicationThread caller, Intent service,
-            String resolvedType, int callingPid, int callingUid, int userId)
+    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
+            int callingPid, int callingUid, String callingPackage, int userId)
             throws TransactionTooLargeException {
         if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
                 + " type=" + resolvedType + " args=" + service.getExtras());
@@ -324,7 +325,7 @@
 
 
         ServiceLookupResult res =
-            retrieveServiceLocked(service, resolvedType,
+            retrieveServiceLocked(service, resolvedType, callingPackage,
                     callingPid, callingUid, userId, true, callerFg);
         if (res == null) {
             return null;
@@ -490,7 +491,7 @@
         }
 
         // If this service is active, make sure it is stopped.
-        ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
+        ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null,
                 Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
         if (r != null) {
             if (r.record != null) {
@@ -508,8 +509,8 @@
         return 0;
     }
 
-    IBinder peekServiceLocked(Intent service, String resolvedType) {
-        ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
+    IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
+        ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage,
                 Binder.getCallingPid(), Binder.getCallingUid(),
                 UserHandle.getCallingUserId(), false, false);
 
@@ -694,8 +695,8 @@
     }
 
     int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
-            String resolvedType, IServiceConnection connection, int flags, int userId)
-            throws TransactionTooLargeException {
+            String resolvedType, IServiceConnection connection, int flags,
+            String callingPackage, int userId) throws TransactionTooLargeException {
         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
                 + " type=" + resolvedType + " conn=" + connection.asBinder()
                 + " flags=0x" + Integer.toHexString(flags));
@@ -746,7 +747,7 @@
         final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
 
         ServiceLookupResult res =
-            retrieveServiceLocked(service, resolvedType,
+            retrieveServiceLocked(service, resolvedType, callingPackage,
                     Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
         if (res == null) {
             return 0;
@@ -1022,7 +1023,7 @@
     }
 
     private ServiceLookupResult retrieveServiceLocked(Intent service,
-            String resolvedType, int callingPid, int callingUid, int userId,
+            String resolvedType, String callingPackage, int callingPid, int callingUid, int userId,
             boolean createIfNeeded, boolean callingFromFg) {
         ServiceRecord r = null;
         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "retrieveServiceLocked: " + service
@@ -1112,7 +1113,18 @@
                         + ", uid=" + callingUid
                         + " requires " + r.permission);
                 return new ServiceLookupResult(null, r.permission);
+            } else if (r.permission != null && callingPackage != null) {
+                final int opCode = AppOpsManager.permissionToOpCode(r.permission);
+                if (opCode != AppOpsManager.OP_NONE && mAm.mAppOpsService.noteOperation(
+                        opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
+                    Slog.w(TAG, "Appop Denial: Accessing service " + r.name
+                            + " from pid=" + callingPid
+                            + ", uid=" + callingUid
+                            + " requires appop " + AppOpsManager.opToName(opCode));
+                    return null;
+                }
             }
+
             if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
                     resolvedType, r.appInfo)) {
                 return null;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d3c8b16..7c537c6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15580,13 +15580,18 @@
 
     @Override
     public ComponentName startService(IApplicationThread caller, Intent service,
-            String resolvedType, int userId) throws TransactionTooLargeException {
+            String resolvedType, String callingPackage, int userId)
+            throws TransactionTooLargeException {
         enforceNotIsolatedCaller("startService");
         // Refuse possible leaked file descriptors
         if (service != null && service.hasFileDescriptors() == true) {
             throw new IllegalArgumentException("File descriptors passed in Intent");
         }
 
+        if (callingPackage == null) {
+            throw new IllegalArgumentException("callingPackage cannot be null");
+        }
+
         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                 "startService: " + service + " type=" + resolvedType);
         synchronized(this) {
@@ -15594,20 +15599,21 @@
             final int callingUid = Binder.getCallingUid();
             final long origId = Binder.clearCallingIdentity();
             ComponentName res = mServices.startServiceLocked(caller, service,
-                    resolvedType, callingPid, callingUid, userId);
+                    resolvedType, callingPid, callingUid, callingPackage, userId);
             Binder.restoreCallingIdentity(origId);
             return res;
         }
     }
 
-    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
+    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
+            String callingPackage, int userId)
             throws TransactionTooLargeException {
         synchronized(this) {
             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                     "startServiceInPackage: " + service + " type=" + resolvedType);
             final long origId = Binder.clearCallingIdentity();
             ComponentName res = mServices.startServiceLocked(null, service,
-                    resolvedType, -1, uid, userId);
+                    resolvedType, -1, uid, callingPackage, userId);
             Binder.restoreCallingIdentity(origId);
             return res;
         }
@@ -15628,14 +15634,19 @@
     }
 
     @Override
-    public IBinder peekService(Intent service, String resolvedType) {
+    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
         enforceNotIsolatedCaller("peekService");
         // Refuse possible leaked file descriptors
         if (service != null && service.hasFileDescriptors() == true) {
             throw new IllegalArgumentException("File descriptors passed in Intent");
         }
+
+        if (callingPackage == null) {
+            throw new IllegalArgumentException("callingPackage cannot be null");
+        }
+
         synchronized(this) {
-            return mServices.peekServiceLocked(service, resolvedType);
+            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
         }
     }
 
@@ -15805,8 +15816,8 @@
     }
 
     public int bindService(IApplicationThread caller, IBinder token, Intent service,
-            String resolvedType, IServiceConnection connection, int flags, int userId)
-            throws TransactionTooLargeException {
+            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
+            int userId) throws TransactionTooLargeException {
         enforceNotIsolatedCaller("bindService");
 
         // Refuse possible leaked file descriptors
@@ -15814,9 +15825,13 @@
             throw new IllegalArgumentException("File descriptors passed in Intent");
         }
 
+        if (callingPackage == null) {
+            throw new IllegalArgumentException("callingPackage cannot be null");
+        }
+
         synchronized(this) {
-            return mServices.bindServiceLocked(caller, token, service, resolvedType,
-                    connection, flags, userId);
+            return mServices.bindServiceLocked(caller, token, service,
+                    resolvedType, connection, flags, callingPackage, userId);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f1c123e..105e36c 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -187,12 +187,12 @@
                 Manifest.permission.CALL_PHONE);
     }
 
-    /** Action not restricted for the calling package. */
-    private static final int ACTION_RESTRICTION_NONE = 0;
-    /** Action restricted for the calling package by not granting a used permission. */
-    private static final int ACTION_RESTRICTION_PERMISSION = 1;
-    /** Action restricted for the calling package by not allowing a used permission's app op. */
-    private static final int ACTION_RESTRICTION_APPOP = 2;
+    /** Action restriction: launching the activity is not restricted. */
+    private static final int ACTIVITY_RESTRICTION_NONE = 0;
+    /** Action restriction: launching the activity is restricted by a permission. */
+    private static final int ACTIVITY_RESTRICTION_PERMISSION = 1;
+    /** Action restriction: launching the activity is restricted by an app op. */
+    private static final int ACTIVITY_RESTRICTION_APPOP = 2;
 
     /** Status Bar Service **/
     private IBinder mToken = new Binder();
@@ -1539,51 +1539,61 @@
             return err;
         }
 
-        final int startAnyPerm = mService.checkPermission(
-                START_ANY_ACTIVITY, callingPid, callingUid);
-        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
-                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
-        final int actionRestriction = getActionRestrictionForCallingPackage(
-                intent.getAction(), callingPackage, callingPid, callingUid);
-
-        if (startAnyPerm != PERMISSION_GRANTED && (componentPerm != PERMISSION_GRANTED
-                || actionRestriction == ACTION_RESTRICTION_PERMISSION)) {
-            if (resultRecord != null) {
-                resultStack.sendActivityResultLocked(-1,
-                    resultRecord, resultWho, requestCode,
-                    Activity.RESULT_CANCELED, null);
-            }
-            String msg;
-            if (actionRestriction == ACTION_RESTRICTION_PERMISSION) {
-                msg = "Permission Denial: starting " + intent.toString()
-                        + " from " + callerApp + " (pid=" + callingPid
-                        + ", uid=" + callingUid + ")" + " with revoked permission "
-                        + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
-            } else if (!aInfo.exported) {
-                msg = "Permission Denial: starting " + intent.toString()
-                        + " from " + callerApp + " (pid=" + callingPid
-                        + ", uid=" + callingUid + ")"
-                        + " not exported from uid " + aInfo.applicationInfo.uid;
-            } else {
-                msg = "Permission Denial: starting " + intent.toString()
-                        + " from " + callerApp + " (pid=" + callingPid
-                        + ", uid=" + callingUid + ")"
-                        + " requires " + aInfo.permission;
-            }
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
-
         boolean abort = false;
 
-        if (startAnyPerm != PERMISSION_GRANTED
-                && actionRestriction == ACTION_RESTRICTION_APPOP) {
-            String msg = "Permission Denial: starting " + intent.toString()
-                    + " from " + callerApp + " (pid=" + callingPid
-                    + ", uid=" + callingUid + ")"
-                    + " requires " + aInfo.permission;
-            Slog.w(TAG, msg);
-            abort = true;
+        final int startAnyPerm = mService.checkPermission(
+                START_ANY_ACTIVITY, callingPid, callingUid);
+
+        if (startAnyPerm != PERMISSION_GRANTED) {
+            final int componentRestriction = getComponentRestrictionForCallingPackage(
+                    aInfo, callingPackage, callingPid, callingUid);
+            final int actionRestriction = getActionRestrictionForCallingPackage(
+                    intent.getAction(), callingPackage, callingPid, callingUid);
+
+            if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
+                    || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
+                if (resultRecord != null) {
+                    resultStack.sendActivityResultLocked(-1,
+                            resultRecord, resultWho, requestCode,
+                            Activity.RESULT_CANCELED, null);
+                }
+                String msg;
+                if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
+                    msg = "Permission Denial: starting " + intent.toString()
+                            + " from " + callerApp + " (pid=" + callingPid
+                            + ", uid=" + callingUid + ")" + " with revoked permission "
+                            + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
+                } else if (!aInfo.exported) {
+                    msg = "Permission Denial: starting " + intent.toString()
+                            + " from " + callerApp + " (pid=" + callingPid
+                            + ", uid=" + callingUid + ")"
+                            + " not exported from uid " + aInfo.applicationInfo.uid;
+                } else {
+                    msg = "Permission Denial: starting " + intent.toString()
+                            + " from " + callerApp + " (pid=" + callingPid
+                            + ", uid=" + callingUid + ")"
+                            + " requires " + aInfo.permission;
+                }
+                Slog.w(TAG, msg);
+                throw new SecurityException(msg);
+            }
+
+            if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
+                String message = "Appop Denial: starting " + intent.toString()
+                        + " from " + callerApp + " (pid=" + callingPid
+                        + ", uid=" + callingUid + ")"
+                        + " requires " + AppOpsManager.permissionToOp(
+                                ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
+                Slog.w(TAG, message);
+                abort = true;
+            } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
+                String message = "Appop Denial: starting " + intent.toString()
+                        + " from " + callerApp + " (pid=" + callingPid
+                        + ", uid=" + callingUid + ")"
+                        + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
+                Slog.w(TAG, message);
+                abort = true;
+            }
         }
 
         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
@@ -1664,15 +1674,40 @@
         return err;
     }
 
+    private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
+            String callingPackage, int callingPid, int callingUid) {
+        if (activityInfo.permission == null) {
+            return ACTIVITY_RESTRICTION_NONE;
+        }
+
+        if (mService.checkComponentPermission(activityInfo.permission, callingPid, callingUid,
+                activityInfo.applicationInfo.uid, activityInfo.exported)
+                == PackageManager.PERMISSION_DENIED) {
+            return ACTIVITY_RESTRICTION_PERMISSION;
+        }
+
+        final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission);
+        if (opCode == AppOpsManager.OP_NONE) {
+            return ACTIVITY_RESTRICTION_NONE;
+        }
+
+        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
+                callingPackage) != AppOpsManager.MODE_ALLOWED) {
+            return ACTIVITY_RESTRICTION_APPOP;
+        }
+
+        return ACTIVITY_RESTRICTION_NONE;
+    }
+
     private int getActionRestrictionForCallingPackage(String action,
             String callingPackage, int callingPid, int callingUid) {
         if (action == null) {
-            return ACTION_RESTRICTION_NONE;
+            return ACTIVITY_RESTRICTION_NONE;
         }
 
         String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
         if (permission == null) {
-            return ACTION_RESTRICTION_NONE;
+            return ACTIVITY_RESTRICTION_NONE;
         }
 
         final PackageInfo packageInfo;
@@ -1681,29 +1716,29 @@
                     .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
         } catch (PackageManager.NameNotFoundException e) {
             Slog.i(TAG, "Cannot find package info for " + callingPackage);
-            return ACTION_RESTRICTION_NONE;
+            return ACTIVITY_RESTRICTION_NONE;
         }
 
         if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
-            return ACTION_RESTRICTION_NONE;
+            return ACTIVITY_RESTRICTION_NONE;
         }
 
         if (mService.checkPermission(permission, callingPid, callingUid) ==
                 PackageManager.PERMISSION_DENIED) {
-            return ACTION_RESTRICTION_PERMISSION;
+            return ACTIVITY_RESTRICTION_PERMISSION;
         }
 
         final int opCode = AppOpsManager.permissionToOpCode(permission);
         if (opCode == AppOpsManager.OP_NONE) {
-            return ACTION_RESTRICTION_NONE;
+            return ACTIVITY_RESTRICTION_NONE;
         }
 
         if (mService.mAppOpsService.noteOperation(opCode, callingUid,
                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
-            return ACTION_RESTRICTION_APPOP;
+            return ACTIVITY_RESTRICTION_APPOP;
         }
 
-        return ACTION_RESTRICTION_NONE;
+        return ACTIVITY_RESTRICTION_NONE;
     }
 
     ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 2335071..30aa411 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -463,7 +463,7 @@
         }
     }
 
-    private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
+    private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
             BroadcastFilter filter, boolean ordered) {
         boolean skip = false;
         if (filter.requiredPermission != null) {
@@ -477,9 +477,23 @@
                         + " requires " + filter.requiredPermission
                         + " due to registered receiver " + filter);
                 skip = true;
+            } else {
+                final int opCode = AppOpsManager.permissionToOpCode(filter.requiredPermission);
+                if (opCode != AppOpsManager.OP_NONE
+                        && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
+                                r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
+                    Slog.w(TAG, "Appop Denial: broadcasting "
+                            + r.intent.toString()
+                            + " from " + r.callerPackage + " (pid="
+                            + r.callingPid + ", uid=" + r.callingUid + ")"
+                            + " requires appop " + AppOpsManager.permissionToOp(
+                                    filter.requiredPermission)
+                            + " due to registered receiver " + filter);
+                    skip = true;
+                }
             }
         }
-        if (!skip && r.requiredPermission != null) {
+        if (!skip) {
             int perm = mService.checkComponentPermission(r.requiredPermission,
                     filter.receiverList.pid, filter.receiverList.uid, -1, true);
             if (perm != PackageManager.PERMISSION_GRANTED) {
@@ -493,17 +507,42 @@
                         + " (uid " + r.callingUid + ")");
                 skip = true;
             }
-        }
-        if (r.appOp != AppOpsManager.OP_NONE) {
-            int mode = mService.mAppOpsService.noteOperation(r.appOp,
-                    filter.receiverList.uid, filter.packageName);
-            if (mode != AppOpsManager.MODE_ALLOWED) {
-                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                        "App op " + r.appOp + " not allowed for broadcast to uid "
-                        + filter.receiverList.uid + " pkg " + filter.packageName);
-                skip = true;
+            int appOp = AppOpsManager.OP_NONE;
+            if (r.requiredPermission != null) {
+                appOp = AppOpsManager.permissionToOpCode(r.requiredPermission);
+                if (appOp != AppOpsManager.OP_NONE
+                        && mService.mAppOpsService.noteOperation(appOp,
+                            filter.receiverList.uid, filter.packageName)
+                                != AppOpsManager.MODE_ALLOWED) {
+                    Slog.w(TAG, "Appop Denial: receiving "
+                            + r.intent.toString()
+                            + " to " + filter.receiverList.app
+                            + " (pid=" + filter.receiverList.pid
+                            + ", uid=" + filter.receiverList.uid + ")"
+                            + " requires appop " + AppOpsManager.permissionToOp(
+                                    r.requiredPermission)
+                            + " due to sender " + r.callerPackage
+                            + " (uid " + r.callingUid + ")");
+                    skip = true;
+                }
+            }
+            if (!skip && r.appOp != appOp && r.appOp != AppOpsManager.OP_NONE
+                    && mService.mAppOpsService.noteOperation(r.appOp,
+                            filter.receiverList.uid, filter.packageName)
+                                    != AppOpsManager.MODE_ALLOWED) {
+                    Slog.w(TAG, "Appop Denial: receiving "
+                            + r.intent.toString()
+                            + " to " + filter.receiverList.app
+                            + " (pid=" + filter.receiverList.pid
+                            + ", uid=" + filter.receiverList.uid + ")"
+                            + " requires appop " + AppOpsManager.permissionToOp(
+                            r.requiredPermission)
+                            + " due to sender " + r.callerPackage
+                            + " (uid " + r.callingUid + ")");
+                    skip = true;
             }
         }
+
         if (!skip) {
             skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
                     r.callingPid, r.resolvedType, filter.receiverList.uid);
@@ -804,8 +843,23 @@
                             + " due to receiver " + component.flattenToShortString());
                 }
                 skip = true;
+            } else if (info.activityInfo.permission != null) {
+                final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
+                if (opCode != AppOpsManager.OP_NONE
+                        && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
+                                r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
+                    Slog.w(TAG, "Appop Denial: broadcasting "
+                            + r.intent.toString()
+                            + " from " + r.callerPackage + " (pid="
+                            + r.callingPid + ", uid=" + r.callingUid + ")"
+                            + " requires appop " + AppOpsManager.permissionToOp(
+                                    info.activityInfo.permission)
+                            + " due to registered receiver "
+                            + component.flattenToShortString());
+                    skip = true;
+                }
             }
-            if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
+            if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
                 r.requiredPermission != null) {
                 try {
                     perm = AppGlobals.getPackageManager().
@@ -825,17 +879,36 @@
                     skip = true;
                 }
             }
-            if (r.appOp != AppOpsManager.OP_NONE) {
-                int mode = mService.mAppOpsService.noteOperation(r.appOp,
-                        info.activityInfo.applicationInfo.uid, info.activityInfo.packageName);
-                if (mode != AppOpsManager.MODE_ALLOWED) {
-                    if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                            "App op " + r.appOp + " not allowed for broadcast to uid "
-                            + info.activityInfo.applicationInfo.uid + " pkg "
-                            + info.activityInfo.packageName);
+            int appOp = AppOpsManager.OP_NONE;
+            if (!skip && r.requiredPermission != null) {
+                appOp = AppOpsManager.permissionToOpCode(r.requiredPermission);
+                if (appOp != AppOpsManager.OP_NONE
+                        && mService.mAppOpsService.noteOperation(appOp,
+                               info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+                                        != AppOpsManager.MODE_ALLOWED) {
+                    Slog.w(TAG, "Appop Denial: receiving "
+                            + r.intent + " to "
+                            + component.flattenToShortString()
+                            + " requires appop " + AppOpsManager.permissionToOp(
+                            r.requiredPermission)
+                            + " due to sender " + r.callerPackage
+                            + " (uid " + r.callingUid + ")");
                     skip = true;
                 }
             }
+            if (!skip && r.appOp != appOp && r.appOp != AppOpsManager.OP_NONE
+                    && mService.mAppOpsService.noteOperation(r.appOp,
+                            info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+                                    != AppOpsManager.MODE_ALLOWED) {
+                Slog.w(TAG, "Appop Denial: receiving "
+                        + r.intent + " to "
+                        + component.flattenToShortString()
+                        + " requires appop " + AppOpsManager.permissionToOp(
+                        r.requiredPermission)
+                        + " due to sender " + r.callerPackage
+                        + " (uid " + r.callingUid + ")");
+                skip = true;
+            }
             if (!skip) {
                 skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
                         r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index ece3ffb..5b46799 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -305,7 +305,8 @@
                         break;
                     case ActivityManager.INTENT_SENDER_SERVICE:
                         try {
-                            owner.startServiceInPackage(uid, finalIntent, resolvedType, userId);
+                            owner.startServiceInPackage(uid, finalIntent,
+                                    resolvedType, key.packageName, userId);
                         } catch (RuntimeException e) {
                             Slog.w(TAG, "Unable to send startService intent", e);
                         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 352e953..305eb8e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -9198,7 +9198,8 @@
         IActivityManager am = ActivityManagerNative.getDefault();
         if (am != null) {
             try {
-                am.startService(null, intent, null, UserHandle.USER_OWNER);
+                am.startService(null, intent, null, mContext.getOpPackageName(),
+                        UserHandle.USER_OWNER);
             } catch (RemoteException e) {
             }
         }