Merge "Set/get allowed capture policy via AudioService." into qt-qpr1-dev
This commit is contained in:
@@ -1251,7 +1251,10 @@ public final class AudioAttributes implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
static int capturePolicyToFlags(@CapturePolicy int capturePolicy, int flags) {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static int capturePolicyToFlags(@CapturePolicy int capturePolicy, int flags) {
|
||||
switch (capturePolicy) {
|
||||
case ALLOW_CAPTURE_BY_NONE:
|
||||
flags |= FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE;
|
||||
|
||||
@@ -1507,23 +1507,22 @@ public class AudioManager {
|
||||
* {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
|
||||
* {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
|
||||
* {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
|
||||
* @throws IllegalArgumentException if the argument is not a valid value.
|
||||
* @throws RuntimeException if the argument is not a valid value.
|
||||
*/
|
||||
public void setAllowedCapturePolicy(@AudioAttributes.CapturePolicy int capturePolicy) {
|
||||
int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
|
||||
// TODO: got trough AudioService and save a cache to restore in case of AP crash
|
||||
// TODO: also pass the package in case multiple packages have the same UID
|
||||
int result = AudioSystem.setAllowedCapturePolicy(Process.myUid(), flags);
|
||||
if (result != AudioSystem.AUDIO_STATUS_OK) {
|
||||
Log.e(TAG, "Could not setAllowedCapturePolicy: " + result);
|
||||
return;
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
int result = service.setAllowedCapturePolicy(capturePolicy);
|
||||
if (result != AudioSystem.AUDIO_STATUS_OK) {
|
||||
Log.e(TAG, "Could not setAllowedCapturePolicy: " + result);
|
||||
return;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
mCapturePolicy = capturePolicy;
|
||||
}
|
||||
|
||||
@AudioAttributes.CapturePolicy
|
||||
private int mCapturePolicy = AudioAttributes.ALLOW_CAPTURE_BY_ALL;
|
||||
|
||||
/**
|
||||
* Return the capture policy.
|
||||
* @return the capture policy set by {@link #setAllowedCapturePolicy(int)} or
|
||||
@@ -1531,7 +1530,13 @@ public class AudioManager {
|
||||
*/
|
||||
@AudioAttributes.CapturePolicy
|
||||
public int getAllowedCapturePolicy() {
|
||||
return mCapturePolicy;
|
||||
int result = AudioAttributes.ALLOW_CAPTURE_BY_ALL;
|
||||
try {
|
||||
result = getService().getAllowedCapturePolicy();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to query allowed capture policy: " + e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
|
||||
@@ -259,6 +259,10 @@ interface IAudioService {
|
||||
|
||||
boolean hasHapticChannels(in Uri uri);
|
||||
|
||||
int setAllowedCapturePolicy(in int capturePolicy);
|
||||
|
||||
int getAllowedCapturePolicy();
|
||||
|
||||
// WARNING: read warning at top of file, new methods that need to be used by native
|
||||
// code via IAudioManager.h need to be added to the top section.
|
||||
}
|
||||
|
||||
@@ -1041,6 +1041,27 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
// Restore capture policies
|
||||
synchronized (mPlaybackMonitor) {
|
||||
HashMap<Integer, Integer> allowedCapturePolicies =
|
||||
mPlaybackMonitor.getAllAllowedCapturePolicies();
|
||||
for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) {
|
||||
int result = AudioSystem.setAllowedCapturePolicy(
|
||||
entry.getKey(),
|
||||
AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0));
|
||||
if (result != AudioSystem.AUDIO_STATUS_OK) {
|
||||
Log.e(TAG, "Failed to restore capture policy, uid: "
|
||||
+ entry.getKey() + ", capture policy: " + entry.getValue()
|
||||
+ ", result: " + result);
|
||||
// When restoring capture policy failed, set the capture policy as
|
||||
// ALLOW_CAPTURE_BY_ALL, which will result in removing the cached
|
||||
// capture policy in PlaybackActivityMonitor.
|
||||
mPlaybackMonitor.setAllowedCapturePolicy(
|
||||
entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onIndicateSystemReady();
|
||||
// indicate the end of reconfiguration phase to audio HAL
|
||||
AudioSystem.setParameters("restarting=false");
|
||||
@@ -7250,6 +7271,43 @@ public class AudioService extends IAudioService.Stub
|
||||
mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether the audio played by this app may or may not be captured by other apps or
|
||||
* the system.
|
||||
*
|
||||
* @param capturePolicy one of
|
||||
* {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
|
||||
* {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
|
||||
* {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
|
||||
* @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed.
|
||||
* @throws IllegalArgumentException if the argument is not a valid value.
|
||||
*/
|
||||
public int setAllowedCapturePolicy(int capturePolicy) {
|
||||
int callingUid = Binder.getCallingUid();
|
||||
int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
synchronized (mPlaybackMonitor) {
|
||||
int result = AudioSystem.setAllowedCapturePolicy(callingUid, flags);
|
||||
if (result == AudioSystem.AUDIO_STATUS_OK) {
|
||||
mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy);
|
||||
}
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the capture policy.
|
||||
* @return the cached capture policy for the calling uid.
|
||||
*/
|
||||
public int getAllowedCapturePolicy() {
|
||||
int callingUid = Binder.getCallingUid();
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
int capturePolicy = mPlaybackMonitor.getAllowedCapturePolicy(callingUid);
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
return capturePolicy;
|
||||
}
|
||||
|
||||
//======================
|
||||
// Audio device management
|
||||
//======================
|
||||
|
||||
@@ -160,6 +160,12 @@ public final class PlaybackActivityMonitor
|
||||
new AudioPlaybackConfiguration(pic, newPiid,
|
||||
Binder.getCallingUid(), Binder.getCallingPid());
|
||||
apc.init();
|
||||
synchronized (mAllowedCapturePolicies) {
|
||||
int uid = apc.getClientUid();
|
||||
if (mAllowedCapturePolicies.containsKey(uid)) {
|
||||
updateAllowedCapturePolicy(apc, mAllowedCapturePolicies.get(uid));
|
||||
}
|
||||
}
|
||||
sEventLogger.log(new NewPlayerEvent(apc));
|
||||
synchronized(mPlayerLock) {
|
||||
mPlayers.put(newPiid, apc);
|
||||
@@ -169,6 +175,13 @@ public final class PlaybackActivityMonitor
|
||||
|
||||
public void playerAttributes(int piid, @NonNull AudioAttributes attr, int binderUid) {
|
||||
final boolean change;
|
||||
synchronized (mAllowedCapturePolicies) {
|
||||
if (mAllowedCapturePolicies.containsKey(binderUid)
|
||||
&& attr.getAllowedCapturePolicy() < mAllowedCapturePolicies.get(binderUid)) {
|
||||
attr = new AudioAttributes.Builder(attr)
|
||||
.setAllowedCapturePolicy(mAllowedCapturePolicies.get(binderUid)).build();
|
||||
}
|
||||
}
|
||||
synchronized(mPlayerLock) {
|
||||
final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
|
||||
if (checkConfigurationCaller(piid, apc, binderUid)) {
|
||||
@@ -284,6 +297,69 @@ public final class PlaybackActivityMonitor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A map of uid to capture policy.
|
||||
*/
|
||||
private final HashMap<Integer, Integer> mAllowedCapturePolicies =
|
||||
new HashMap<Integer, Integer>();
|
||||
|
||||
/**
|
||||
* Cache allowed capture policy, which specifies whether the audio played by the app may or may
|
||||
* not be captured by other apps or the system.
|
||||
*
|
||||
* @param uid the uid of requested app
|
||||
* @param capturePolicy one of
|
||||
* {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
|
||||
* {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
|
||||
* {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
|
||||
*/
|
||||
public void setAllowedCapturePolicy(int uid, int capturePolicy) {
|
||||
synchronized (mAllowedCapturePolicies) {
|
||||
if (capturePolicy == AudioAttributes.ALLOW_CAPTURE_BY_ALL) {
|
||||
// When the capture policy is ALLOW_CAPTURE_BY_ALL, it is okay to
|
||||
// remove it from cached capture policy as it is the default value.
|
||||
mAllowedCapturePolicies.remove(uid);
|
||||
return;
|
||||
} else {
|
||||
mAllowedCapturePolicies.put(uid, capturePolicy);
|
||||
}
|
||||
}
|
||||
synchronized (mPlayerLock) {
|
||||
for (AudioPlaybackConfiguration apc : mPlayers.values()) {
|
||||
if (apc.getClientUid() == uid) {
|
||||
updateAllowedCapturePolicy(apc, capturePolicy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the capture policy for given uid.
|
||||
* @param uid the uid to query its cached capture policy.
|
||||
* @return cached capture policy for given uid or AudioAttributes.ALLOW_CAPTURE_BY_ALL
|
||||
* if there is not cached capture policy.
|
||||
*/
|
||||
public int getAllowedCapturePolicy(int uid) {
|
||||
return mAllowedCapturePolicies.getOrDefault(uid, AudioAttributes.ALLOW_CAPTURE_BY_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all cached capture policies.
|
||||
*/
|
||||
public HashMap<Integer, Integer> getAllAllowedCapturePolicies() {
|
||||
return mAllowedCapturePolicies;
|
||||
}
|
||||
|
||||
private void updateAllowedCapturePolicy(AudioPlaybackConfiguration apc, int capturePolicy) {
|
||||
AudioAttributes attr = apc.getAudioAttributes();
|
||||
if (attr.getAllowedCapturePolicy() >= capturePolicy) {
|
||||
return;
|
||||
}
|
||||
apc.handleAudioAttributesEvent(
|
||||
new AudioAttributes.Builder(apc.getAudioAttributes())
|
||||
.setAllowedCapturePolicy(capturePolicy).build());
|
||||
}
|
||||
|
||||
// Implementation of AudioPlaybackConfiguration.PlayerDeathMonitor
|
||||
@Override
|
||||
public void playerDeath(int piid) {
|
||||
@@ -331,6 +407,12 @@ public final class PlaybackActivityMonitor
|
||||
// log
|
||||
sEventLogger.dump(pw);
|
||||
}
|
||||
synchronized (mAllowedCapturePolicies) {
|
||||
pw.println("\n allowed capture policies:");
|
||||
for (HashMap.Entry<Integer, Integer> entry : mAllowedCapturePolicies.entrySet()) {
|
||||
pw.println(" uid: " + entry.getKey() + " policy: " + entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user