Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b6dd0ec authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support noted appops collection in native code"

parents e6227bc0 66a87772
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -86,10 +86,8 @@ cc_library_shared {
        vendor: {
            exclude_srcs: [
                "ActivityManager.cpp",
                "AppOpsManager.cpp",
                "IActivityManager.cpp",
                "IAppOpsCallback.cpp",
                "IAppOpsService.cpp",
                "IBatteryStats.cpp",
                "IMediaResourceMonitor.cpp",
                "IPermissionController.cpp",
+84 −2
Original line number Diff line number Diff line
@@ -21,10 +21,18 @@

#include <utils/SystemClock.h>

#include <sys/types.h>

#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "AppOpsManager"

namespace android {

namespace {

#ifndef __ANDROID_VNDK__
#if defined(__BRILLO__)
// Because Brillo has no application model, security policy is managed
// statically (at build time) with SELinux controls.
@@ -33,13 +41,17 @@ const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_ALLOWED;
#else
const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_IGNORED;
#endif  // defined(__BRILLO__)
#endif // __ANDROID_VNDK__

}  // namespace

static String16 _appops("appops");
#ifndef __ANDROID_VNDK__
static pthread_mutex_t gTokenMutex = PTHREAD_MUTEX_INITIALIZER;
#endif // __ANDROID_VNDK__
static sp<IBinder> gToken;

#ifndef __ANDROID_VNDK__
static const sp<IBinder>& getToken(const sp<IAppOpsService>& service) {
    pthread_mutex_lock(&gTokenMutex);
    if (gToken == nullptr || gToken->pingBinder() != NO_ERROR) {
@@ -48,6 +60,17 @@ static const sp<IBinder>& getToken(const sp<IAppOpsService>& service) {
    pthread_mutex_unlock(&gTokenMutex);
    return gToken;
}
#endif // __ANDROID_VNDK__

thread_local uint64_t notedAppOpsInThisBinderTransaction[2];
thread_local int32_t uidOfThisBinderTransaction = -1;

// Whether an appop should be collected: 0 == not initialized, 1 == don't note, 2 == note
#ifndef __ANDROID_VNDK__
uint8_t appOpsToNote[AppOpsManager::_NUM_OP] = {0};
#else
uint8_t appOpsToNote[128] = {0};
#endif // __ANDROID_VNDK__

AppOpsManager::AppOpsManager()
{
@@ -85,6 +108,7 @@ sp<IAppOpsService> AppOpsManager::getService()
}
#endif  // defined(__BRILLO__)

#ifndef __ANDROID_VNDK__
int32_t AppOpsManager::checkOp(int32_t op, int32_t uid, const String16& callingPackage)
{
    sp<IAppOpsService> service = getService();
@@ -102,18 +126,41 @@ int32_t AppOpsManager::checkAudioOpNoThrow(int32_t op, int32_t usage, int32_t ui
}

int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) {
    return noteOp(op, uid, callingPackage, String16("noteOp from native code"));
}

int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage,
        const String16& message) {
    sp<IAppOpsService> service = getService();
    return service != nullptr
    int32_t mode = service != nullptr
            ? service->noteOperation(op, uid, callingPackage)
            : APP_OPS_MANAGER_UNAVAILABLE_MODE;

    if (mode == AppOpsManager::MODE_ALLOWED) {
        markAppOpNoted(uid, callingPackage, op, message);
    }

    return mode;
}

int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage,
        bool startIfModeDefault) {
    return startOpNoThrow(op, uid, callingPackage, startIfModeDefault,
            String16("startOpNoThrow from native code"));
}

int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage,
        bool startIfModeDefault, const String16& message) {
    sp<IAppOpsService> service = getService();
    return service != nullptr
    int32_t mode = service != nullptr
            ? service->startOperation(getToken(service), op, uid, callingPackage,
                    startIfModeDefault) : APP_OPS_MANAGER_UNAVAILABLE_MODE;

    if (mode == AppOpsManager::MODE_ALLOWED) {
        markAppOpNoted(uid, callingPackage, op, message);
    }

    return mode;
}

void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) {
@@ -146,5 +193,40 @@ int32_t AppOpsManager::permissionToOpCode(const String16& permission) {
    return -1;
}

#endif // __ANDROID_VNDK__

bool AppOpsManager::shouldCollectNotes(int32_t opcode) {
    sp<IAppOpsService> service = getService();
    if (service != nullptr) {
        return service->shouldCollectNotes(opcode);
    }
    return false;
}

void AppOpsManager::markAppOpNoted(int32_t uid, const String16& packageName, int32_t opCode,
         const String16& message) {
    // check it the appops needs to be collected and cache result
    if (appOpsToNote[opCode] == 0) {
        if (shouldCollectNotes(opCode)) {
            appOpsToNote[opCode] = 2;
        } else {
            appOpsToNote[opCode] = 1;
        }
    }

    if (appOpsToNote[opCode] != 2) {
        return;
    }

    noteAsyncOp(String16(), uid, packageName, opCode, message);
}

void AppOpsManager::noteAsyncOp(const String16& callingPackageName, int32_t uid,
         const String16& packageName, int32_t opCode, const String16& message) {
    sp<IAppOpsService> service = getService();
    if (service != nullptr) {
        return service->noteAsyncOp(callingPackageName, uid, packageName, opCode, message);
    }
}

}; // namespace android
+61 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ public:
    {
    }

#ifndef __ANDROID_VNDK__
    virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) {
        Parcel data, reply;
        data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
@@ -111,7 +112,6 @@ public:
        return reply.readStrongBinder();
    }


    virtual int32_t permissionToOpCode(const String16& permission) {
        Parcel data, reply;
        data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
@@ -137,6 +137,45 @@ public:
        }
        return reply.readInt32();
    }

#endif
    virtual void noteAsyncOp(const String16& callingPackageName, int32_t uid,
            const String16& packageName, int32_t opCode, const String16& message) {
        Parcel data, reply;
        data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());

        // Convert empty callingPackage into null string
        if (callingPackageName.size() != 0) {
            data.writeString16(callingPackageName);
        } else {
            data.writeString16(nullptr, 0);
        }

        data.writeInt32(uid);

        // Convert empty packageName into null string
        if (packageName.size() != 0) {
            data.writeString16(packageName);
        } else {
            data.writeString16(nullptr, 0);
        }

        data.writeInt32(opCode);
        data.writeString16(message);
        remote()->transact(NOTE_ASYNC_OP_TRANSACTION, data, &reply);
    }

    virtual bool shouldCollectNotes(int32_t opCode) {
        Parcel data, reply;
        data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
        data.writeInt32(opCode);
        remote()->transact(SHOULD_COLLECT_NOTES_TRANSACTION, data, &reply);
        // fail on exception
        if (reply.readExceptionCode() != 0) {
            return false;
        }
        return reply.readBool();
    }
};

IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
@@ -149,6 +188,7 @@ status_t BnAppOpsService::onTransact(
{
    //printf("AppOpsService received: "); data.print();
    switch(code) {
#ifndef __ANDROID_VNDK__
        case CHECK_OPERATION_TRANSACTION: {
            CHECK_INTERFACE(IAppOpsService, data, reply);
            int32_t code = data.readInt32();
@@ -234,6 +274,26 @@ status_t BnAppOpsService::onTransact(
            reply->writeInt32(res);
            return NO_ERROR;
        } break;
#endif // __ANDROID_VNDK__
        case NOTE_ASYNC_OP_TRANSACTION: {
            CHECK_INTERFACE(IAppOpsService, data, reply);
            String16 callingPackageName = data.readString16();
            int32_t uid = data.readInt32();
            String16 packageName = data.readString16();
            int32_t opCode = data.readInt32();
            String16 message = data.readString16();
            noteAsyncOp(callingPackageName, uid, packageName, opCode, message);
            reply->writeNoException();
            return NO_ERROR;
        } break;
        case SHOULD_COLLECT_NOTES_TRANSACTION: {
            CHECK_INTERFACE(IAppOpsService, data, reply);
            int32_t opCode = data.readInt32();
            bool shouldCollect = shouldCollectNotes(opCode);
            reply->writeNoException();
            reply->writeBool(shouldCollect);
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+29 −6
Original line number Diff line number Diff line
@@ -17,8 +17,6 @@
#ifndef ANDROID_APP_OPS_MANAGER_H
#define ANDROID_APP_OPS_MANAGER_H

#ifndef __ANDROID_VNDK__

#include <binder/IAppOpsService.h>

#include <utils/threads.h>
@@ -35,6 +33,7 @@ public:
        MODE_ERRORED = IAppOpsService::MODE_ERRORED
    };

#ifndef __ANDROID_VNDK__
    enum {
        OP_NONE = -1,
        OP_COARSE_LOCATION = 0,
@@ -109,34 +108,58 @@ public:
        OP_START_FOREGROUND = 76,
        OP_BLUETOOTH_SCAN = 77,
        OP_USE_BIOMETRIC = 78,
        OP_ACTIVITY_RECOGNITION = 79,
        OP_SMS_FINANCIAL_TRANSACTIONS = 80,
        OP_READ_MEDIA_AUDIO = 81,
        OP_WRITE_MEDIA_AUDIO = 82,
        OP_READ_MEDIA_VIDEO = 83,
        OP_WRITE_MEDIA_VIDEO = 84,
        OP_READ_MEDIA_IMAGES = 85,
        OP_WRITE_MEDIA_IMAGES = 86,
        OP_LEGACY_STORAGE = 87,
        OP_ACCESS_ACCESSIBILITY = 88,
        OP_READ_DEVICE_IDENTIFIERS = 89,
        _NUM_OP = 90
    };
#endif // __ANDROID_VNDK__

    AppOpsManager();

#ifndef __ANDROID_VNDK__
    int32_t checkOp(int32_t op, int32_t uid, const String16& callingPackage);
    int32_t checkAudioOpNoThrow(int32_t op, int32_t usage, int32_t uid,
            const String16& callingPackage);
    // @Deprecated, use noteOp(int32_t, int32_t uid, const String16&, const String16&) instead
    int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage);
    int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage,
            const String16& message);
    // @Deprecated, use startOpNoThrow(int32_t, int32_t, const String16&, bool, const String16&)
    // instead
    int32_t startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage,
            bool startIfModeDefault);
    int32_t startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage,
            bool startIfModeDefault, const String16& message);
    void finishOp(int32_t op, int32_t uid, const String16& callingPackage);
    void startWatchingMode(int32_t op, const String16& packageName,
            const sp<IAppOpsCallback>& callback);
    void stopWatchingMode(const sp<IAppOpsCallback>& callback);
    int32_t permissionToOpCode(const String16& permission);

#endif // __ANDROID_VNDK__
    void noteAsyncOp(const String16& callingPackageName, int32_t uid, const String16& packageName,
            int32_t opCode, const String16& message);
private:
    Mutex mLock;
    sp<IAppOpsService> mService;

    sp<IAppOpsService> getService();
    void markAppOpNoted(int32_t uid, const String16& packageName, int32_t opCode,
            const String16& message);
    bool shouldCollectNotes(int32_t opCode);
};


}; // namespace android

// ---------------------------------------------------------------------------
#else // __ANDROID_VNDK__
#error "This header is not visible to vendors"
#endif // __ANDROID_VNDK__

#endif // ANDROID_APP_OPS_MANAGER_H
+10 −5
Original line number Diff line number Diff line
@@ -19,8 +19,8 @@
#define ANDROID_IAPP_OPS_SERVICE_H

#ifndef __ANDROID_VNDK__

#include <binder/IAppOpsCallback.h>
#endif
#include <binder/IInterface.h>

namespace android {
@@ -32,6 +32,7 @@ class IAppOpsService : public IInterface
public:
    DECLARE_META_INTERFACE(AppOpsService)

#ifndef __ANDROID_VNDK__
    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(const sp<IBinder>& token, int32_t code, int32_t uid,
@@ -45,8 +46,13 @@ public:
    virtual int32_t permissionToOpCode(const String16& permission) = 0;
    virtual int32_t checkAudioOperation(int32_t code, int32_t usage,int32_t uid,
            const String16& packageName) = 0;
#endif // __ANDROID_VNDK__
    virtual void noteAsyncOp(const String16& callingPackageName, int32_t uid,
            const String16& packageName, int32_t opCode, const String16& message) = 0;
    virtual bool shouldCollectNotes(int32_t opCode) = 0;

    enum {
#ifndef __ANDROID_VNDK__
        CHECK_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
        NOTE_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+1,
        START_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+2,
@@ -56,6 +62,9 @@ public:
        GET_TOKEN_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+6,
        PERMISSION_TO_OP_CODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+7,
        CHECK_AUDIO_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+8,
#endif // __ANDROID_VNDK__
        NOTE_ASYNC_OP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+9,
        SHOULD_COLLECT_NOTES_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+10,
    };

    enum {
@@ -81,8 +90,4 @@ public:

}; // namespace android

#else // __ANDROID_VNDK__
#error "This header is not visible to vendors"
#endif // __ANDROID_VNDK__

#endif // ANDROID_IAPP_OPS_SERVICE_H