摘要:
1.在Android9中为了防止App后台录音,实际上已经存在一个静音的接口用于禁止App录音,不过这个接口存在两个问题:1)仅在C++层供系统调用,没有暴露给App调用;2)这个接口是根据uid静音的,很多时候App开发人员为了图省事都将自己的App设置为系统级别的App,如果根据uid静音,那么系统级别的uid都是1000,就会造成误伤,所以我们增加了根据包名静音的接口并暴露给上层调用
2.并发录音是项目中很常见的需求,其实Android9中已经包含并发录音的代码,只不过被屏蔽了,只要稍加修改就可以实现功能
一、根据包名静音接口的实现
1.Java层实现
我决定将接口设置在CarAudioService中(因为本人是搞车机的),其实CarAudioService里面的很多接口最终都会调用到AudioService里面,这个接口也不例外,闲话少说,上代码:
CarAudioManager.java:
/**
* setRecordSilenced according to uid
*
* @hide
*/
@SystemApi
public int setRecordSilenced(String packageName, boolean silenced) throws CarNotConnectedException {
try {
return mService.setRecordSilenced(packageName, silenced);
} catch (RemoteException e) {
Log.e(CarLibLog.TAG_CAR, "setRecordSilenced failed", e);
throw new CarNotConnectedException(e);
}
}
ICarAudio.aidl:
int setRecordSilenced(String packageName, boolean silenced);
CarAudioService.java:
@Override
public int setRecordSilenced(String packageName, boolean silenced) {
return mAudioManager.setRecordSilenced(packageName, silenced);
}
AudioManager.java:
/**
* setRecordSilenced according to packageName
*
* @hide
*/
public int setRecordSilenced(String packageName, boolean silenced) {
final IAudioService service = getService();
try {
return service.setRecordSilenced(packageName, silenced);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
IAudioService.aidl:
int setRecordSilenced(String packageName, boolean silenced);
AudioService.java:
/** @hide */
@Override
public int setRecordSilenced(String packageName, boolean silenced) {
return AudioSystem.setRecordSilenced(packageName, silenced);
}
AudioSystem.java:
/**
* @hide
*/
public static native int setRecordSilenced(String packageName, boolean silenced);
2.JNI层实现
android_media_AudioSystem.cpp:
static jint
android_media_AudioSystem_setRecordSilenced(JNIEnv *env, jobject thiz, jstring packageName, jboolean silenced)
{
const char *c_packageName = env->GetStringUTFChars(packageName, NULL);
int status = check_AudioSystem_Command(AudioSystem::setRecordSilenced(c_packageName, silenced));
env->ReleaseStringUTFChars(packageName, c_packageName);
return (jint) status;
}
static const JNINativeMethod gMethods[] = {
......
{
"setRecordSilenced", "(Ljava/lang/String;Z)I", (void *)android_media_AudioSystem_setRecordSilenced},
......
hiddenapi-light-greylist.txt:
Landroid/media/AudioSystem;->setRecordSilenced(Ljava/lang/String;Z)I
hiddenapi-private-dex.txt:
Landroid/media/AudioSystem;->setRecordSilenced(Ljava/lang/String;Z)I
3.C++层实现
AudioSystem.cpp:
status_t AudioSystem::setRecordSilenced(const char *packageName, bool silenced)
{
ALOGV("setRecordSilencedByName : packageName = %s, is silenced = %d", packageName, silenced);
const sp<IAudioPolicyService>& aps = AudioSyste