Merge "Follow framework change to track started ops by proc."
diff --git a/include/binder/IAppOpsService.h b/include/binder/IAppOpsService.h
index 7cb55e5..193e9cc 100644
--- a/include/binder/IAppOpsService.h
+++ b/include/binder/IAppOpsService.h
@@ -32,11 +32,14 @@
 
     virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) = 0;
     virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) = 0;
-    virtual int32_t startOperation(int32_t code, int32_t uid, const String16& packageName) = 0;
-    virtual void finishOperation(int32_t code, int32_t uid, const String16& packageName) = 0;
+    virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
+            const String16& packageName) = 0;
+    virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
+            const String16& packageName) = 0;
     virtual void startWatchingMode(int32_t op, const String16& packageName,
             const sp<IAppOpsCallback>& callback) = 0;
     virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0;
+    virtual sp<IBinder> getToken(const sp<IBinder>& clientToken) = 0;
 
     enum {
         CHECK_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
@@ -44,7 +47,8 @@
         START_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+2,
         FINISH_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+3,
         START_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+4,
-        STOP_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+5
+        STOP_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+5,
+        GET_TOKEN_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+6,
     };
 
     enum {
diff --git a/libs/binder/AppOpsManager.cpp b/libs/binder/AppOpsManager.cpp
index 7ac1b11..99c2747 100644
--- a/libs/binder/AppOpsManager.cpp
+++ b/libs/binder/AppOpsManager.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <binder/AppOpsManager.h>
+#include <binder/Binder.h>
 #include <binder/IServiceManager.h>
 
 #include <utils/SystemClock.h>
@@ -22,6 +23,16 @@
 namespace android {
 
 static String16 _appops("appops");
+static pthread_mutex_t gTokenMutex = PTHREAD_MUTEX_INITIALIZER;
+static sp<IBinder> gToken;
+
+static const sp<IBinder>& getToken(const sp<IAppOpsService>& service) {
+    pthread_mutex_lock(&gTokenMutex);
+    if (gToken == NULL) {
+        gToken = service->getToken(new BBinder());
+    }
+    return gToken;
+}
 
 AppOpsManager::AppOpsManager()
 {
@@ -66,13 +77,14 @@
 
 int32_t AppOpsManager::startOp(int32_t op, int32_t uid, const String16& callingPackage) {
     sp<IAppOpsService> service = getService();
-    return service != NULL ? service->startOperation(op, uid, callingPackage) : MODE_IGNORED;
+    return service != NULL ? service->startOperation(getToken(service), op, uid, callingPackage)
+            : MODE_IGNORED;
 }
 
 void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) {
     sp<IAppOpsService> service = getService();
     if (service != NULL) {
-        service->finishOperation(op, uid, callingPackage);
+        service->finishOperation(getToken(service), op, uid, callingPackage);
     }
 }
 
diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp
index 282b30f..471e3e9 100644
--- a/libs/binder/IAppOpsService.cpp
+++ b/libs/binder/IAppOpsService.cpp
@@ -61,9 +61,11 @@
         return reply.readInt32();
     }
 
-    virtual int32_t startOperation(int32_t code, int32_t uid, const String16& packageName) {
+    virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
+                const String16& packageName) {
         Parcel data, reply;
         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
+        data.writeStrongBinder(token);
         data.writeInt32(code);
         data.writeInt32(uid);
         data.writeString16(packageName);
@@ -73,9 +75,11 @@
         return reply.readInt32();
     }
 
-    virtual void finishOperation(int32_t code, int32_t uid, const String16& packageName) {
+    virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
+            const String16& packageName) {
         Parcel data, reply;
         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
+        data.writeStrongBinder(token);
         data.writeInt32(code);
         data.writeInt32(uid);
         data.writeString16(packageName);
@@ -98,6 +102,16 @@
         data.writeStrongBinder(callback->asBinder());
         remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
     }
+
+    virtual sp<IBinder> getToken(const sp<IBinder>& clientToken) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
+        data.writeStrongBinder(clientToken);
+        remote()->transact(GET_TOKEN_TRANSACTION, data, &reply);
+        // fail on exception
+        if (reply.readExceptionCode() != 0) return NULL;
+        return reply.readStrongBinder();
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
@@ -131,20 +145,22 @@
         } break;
         case START_OPERATION_TRANSACTION: {
             CHECK_INTERFACE(IAppOpsService, data, reply);
+            sp<IBinder> token = data.readStrongBinder();
             int32_t code = data.readInt32();
             int32_t uid = data.readInt32();
             String16 packageName = data.readString16();
-            int32_t res = startOperation(code, uid, packageName);
+            int32_t res = startOperation(token, code, uid, packageName);
             reply->writeNoException();
             reply->writeInt32(res);
             return NO_ERROR;
         } break;
         case FINISH_OPERATION_TRANSACTION: {
             CHECK_INTERFACE(IAppOpsService, data, reply);
+            sp<IBinder> token = data.readStrongBinder();
             int32_t code = data.readInt32();
             int32_t uid = data.readInt32();
             String16 packageName = data.readString16();
-            finishOperation(code, uid, packageName);
+            finishOperation(token, code, uid, packageName);
             reply->writeNoException();
             return NO_ERROR;
         } break;
@@ -164,6 +180,14 @@
             reply->writeNoException();
             return NO_ERROR;
         } break;
+        case GET_TOKEN_TRANSACTION: {
+            CHECK_INTERFACE(IAppOpsService, data, reply);
+            sp<IBinder> clientToken = data.readStrongBinder();
+            sp<IBinder> token = getToken(clientToken);
+            reply->writeNoException();
+            reply->writeStrongBinder(token);
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }