AppOps: Check user permission before audio recording.
Add permission check before audio recording.
Change-Id: I55c8397df3169e031bba951cf180fa8c5f4c4ce0
Conflicts:
media/java/android/media/AudioRecord.java
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index c26f01f..753df44 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -1,4 +1,7 @@
/*
+ * 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 @@
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 @@
"()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
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 540b8d1..8db18d3 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -1,4 +1,7 @@
/*
+ * 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.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 @@
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 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 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 @@
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