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

Commit f3639249 authored by Shashank Mittal's avatar Shashank Mittal Committed by Linux Build Service Account
Browse files

AppOps: Check user permission before audio recording.

Add permission check before audio recording.

Change-Id: I55c8397df3169e031bba951cf180fa8c5f4c4ce0
Conflicts:
media/java/android/media/AudioRecord.java
parent 1941c97b
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,6 +21,9 @@

#define LOG_TAG "AudioRecord-JNI"

#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>

#include <inttypes.h>
#include <jni.h>
#include <JNIHelp.h>
@@ -573,6 +579,23 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th
    return frameCount * channelCount * audio_bytes_per_sample(format);
}

// ----------------------------------------------------------------------------
// returns the AppOps Permission of package
static jint android_media_AudioRecord_check_permission(JNIEnv *env,  jobject thiz,
    jstring packageName) {

    // Convert client name jstring to String16
    const char16_t *rawClientName = env->GetStringChars(packageName, NULL);
    jsize rawClientNameLen = env->GetStringLength(packageName);
    String16 clientName(rawClientName, rawClientNameLen);
    env->ReleaseStringChars(packageName, rawClientName);

    AppOpsManager appOpsManager;

    // Get UID here for permission checking
    uid_t clientUid = IPCThreadState::self()->getCallingUid();
    return appOpsManager.noteOp(AppOpsManager::OP_RECORD_AUDIO, clientUid, clientName);
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -598,6 +621,8 @@ static JNINativeMethod gMethods[] = {
                             "()I",    (void *)android_media_AudioRecord_get_pos_update_period},
    {"native_get_min_buff_size",
                             "(III)I",   (void *)android_media_AudioRecord_get_min_buff_size},
    {"native_check_permission",
                             "(Ljava/lang/String;)I", (void *)android_media_AudioRecord_check_permission},
};

// field names found in android/media/AudioRecord.java
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,6 +24,8 @@ import java.nio.ByteBuffer;
import java.util.Iterator;

import android.os.Binder;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -610,6 +615,10 @@ public class AudioRecord
        return mSessionId;
    }

    private boolean isAudioRecordAllowed() {
        String packageName = ActivityThread.currentPackageName();
        return native_check_permission(packageName) == AppOpsManager.MODE_ALLOWED;
    }
    //---------------------------------------------------------
    // Transport control methods
    //--------------------
@@ -619,6 +628,10 @@ public class AudioRecord
     */
    public void startRecording()
    throws IllegalStateException {
        if (!isAudioRecordAllowed()) {
            Log.e(TAG, "User permission denied!");
            return;
        }
        if (mState != STATE_INITIALIZED) {
            throw new IllegalStateException("startRecording() called on an "
                    + "uninitialized AudioRecord.");
@@ -642,6 +655,10 @@ public class AudioRecord
     */
    public void startRecording(MediaSyncEvent syncEvent)
    throws IllegalStateException {
        if (!isAudioRecordAllowed()) {
            Log.e(TAG, "User permission denied!");
            return;
        }
        if (mState != STATE_INITIALIZED) {
            throw new IllegalStateException("startRecording() called on an "
                    + "uninitialized AudioRecord.");
@@ -963,6 +980,8 @@ public class AudioRecord
    static private native final int native_get_min_buff_size(
            int sampleRateInHz, int channelCount, int audioFormat);

    private native final int native_check_permission(String packageName);


    //---------------------------------------------------------
    // Utility methods