Loading media/java/android/media/PlayerBase.java +74 −31 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IAppOpsService; import java.lang.IllegalArgumentException; import java.lang.IllegalArgumentException; import java.lang.ref.WeakReference; import java.util.Objects; import java.util.Objects; /** /** Loading @@ -45,11 +46,11 @@ import java.util.Objects; */ */ public abstract class PlayerBase { public abstract class PlayerBase { private final static String TAG = "PlayerBase"; private static final String TAG = "PlayerBase"; private final static boolean DEBUG = false; private static final boolean DEBUG = false; private static IAudioService sService; //lazy initialization, use getService() private static IAudioService sService; //lazy initialization, use getService() /** Debug app ops */ /** Debug app ops */ protected static final boolean DEBUG_APP_OPS = Log.isLoggable(TAG + ".AO", Log.DEBUG); private static final boolean DEBUG_APP_OPS = false; // parameters of the player that affect AppOps // parameters of the player that affect AppOps protected AudioAttributes mAttributes; protected AudioAttributes mAttributes; Loading Loading @@ -94,19 +95,9 @@ public abstract class PlayerBase { IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE); IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE); mAppOps = IAppOpsService.Stub.asInterface(b); mAppOps = IAppOpsService.Stub.asInterface(b); // initialize mHasAppOpsPlayAudio // initialize mHasAppOpsPlayAudio synchronized (mLock) { updateAppOpsPlayAudio(); updateAppOpsPlayAudio_sync(); } // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed mAppOpsCallback = new IAppOpsCallback.Stub() { mAppOpsCallback = new IAppOpsCallbackWrapper(this); public void opChanged(int op, int uid, String packageName) { synchronized (mLock) { if (op == AppOpsManager.OP_PLAY_AUDIO) { updateAppOpsPlayAudio_sync(); } } } }; try { try { mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO, mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO, ActivityThread.currentPackageName(), mAppOpsCallback); ActivityThread.currentPackageName(), mAppOpsCallback); Loading @@ -114,10 +105,8 @@ public abstract class PlayerBase { mHasAppOpsPlayAudio = false; mHasAppOpsPlayAudio = false; } } try { try { if (mIPlayer == null) { newPiid = getService().trackPlayer( throw new IllegalStateException("Cannot register a player with a null mIPlayer"); new PlayerIdCard(mImplType, mAttributes, new IPlayerWrapper(this))); } newPiid = getService().trackPlayer(new PlayerIdCard(mImplType, mAttributes, mIPlayer)); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, "Error talking to audio service, player will not be tracked", e); Log.e(TAG, "Error talking to audio service, player will not be tracked", e); } } Loading Loading @@ -259,6 +248,12 @@ public abstract class PlayerBase { } } } } private void updateAppOpsPlayAudio() { synchronized (mLock) { updateAppOpsPlayAudio_sync(); } } /** /** * To be called whenever a condition that might affect audibility of this player is updated. * To be called whenever a condition that might affect audibility of this player is updated. * Must be called synchronized on mLock. * Must be called synchronized on mLock. Loading Loading @@ -405,48 +400,96 @@ public abstract class PlayerBase { abstract void playerPause(); abstract void playerPause(); abstract void playerStop(); abstract void playerStop(); //===================================================================== private static class IAppOpsCallbackWrapper extends IAppOpsCallback.Stub { private final WeakReference<PlayerBase> mWeakPB; public IAppOpsCallbackWrapper(PlayerBase pb) { mWeakPB = new WeakReference<PlayerBase>(pb); } @Override public void opChanged(int op, int uid, String packageName) { if (op == AppOpsManager.OP_PLAY_AUDIO) { if (DEBUG_APP_OPS) { Log.v(TAG, "opChanged: op=PLAY_AUDIO pack=" + packageName); } final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.updateAppOpsPlayAudio(); } } } } //===================================================================== //===================================================================== /** /** * Implementation of IPlayer for all subclasses of PlayerBase * Wrapper around an implementation of IPlayer for all subclasses of PlayerBase * that doesn't keep a strong reference on PlayerBase */ */ private IPlayer mIPlayer = new IPlayer.Stub() { private static class IPlayerWrapper extends IPlayer.Stub { private final WeakReference<PlayerBase> mWeakPB; public IPlayerWrapper(PlayerBase pb) { mWeakPB = new WeakReference<PlayerBase>(pb); } @Override @Override public void start() { public void start() { playerStart(); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.playerStart(); } } } @Override @Override public void pause() { public void pause() { playerPause(); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.playerPause(); } } } @Override @Override public void stop() { public void stop() { playerStop(); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.playerStop(); } } } @Override @Override public void setVolume(float vol) { public void setVolume(float vol) { baseSetVolume(vol, vol); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.baseSetVolume(vol, vol); } } } @Override @Override public void setPan(float pan) { public void setPan(float pan) { baseSetPan(pan); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.baseSetPan(pan); } } } @Override @Override public void setStartDelayMs(int delayMs) { public void setStartDelayMs(int delayMs) { baseSetStartDelayMs(delayMs); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.baseSetStartDelayMs(delayMs); } } } @Override @Override public void applyVolumeShaper( public void applyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation) { @NonNull VolumeShaper.Operation operation) { /* void */ playerApplyVolumeShaper(configuration, operation); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.playerApplyVolumeShaper(configuration, operation); } } } } }; //===================================================================== //===================================================================== /** /** Loading @@ -455,8 +498,8 @@ public abstract class PlayerBase { public static class PlayerIdCard implements Parcelable { public static class PlayerIdCard implements Parcelable { public final int mPlayerType; public final int mPlayerType; public final static int AUDIO_ATTRIBUTES_NONE = 0; public static final int AUDIO_ATTRIBUTES_NONE = 0; public final static int AUDIO_ATTRIBUTES_DEFINED = 1; public static final int AUDIO_ATTRIBUTES_DEFINED = 1; public final AudioAttributes mAttributes; public final AudioAttributes mAttributes; public final IPlayer mIPlayer; public final IPlayer mIPlayer; Loading Loading
media/java/android/media/PlayerBase.java +74 −31 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IAppOpsService; import java.lang.IllegalArgumentException; import java.lang.IllegalArgumentException; import java.lang.ref.WeakReference; import java.util.Objects; import java.util.Objects; /** /** Loading @@ -45,11 +46,11 @@ import java.util.Objects; */ */ public abstract class PlayerBase { public abstract class PlayerBase { private final static String TAG = "PlayerBase"; private static final String TAG = "PlayerBase"; private final static boolean DEBUG = false; private static final boolean DEBUG = false; private static IAudioService sService; //lazy initialization, use getService() private static IAudioService sService; //lazy initialization, use getService() /** Debug app ops */ /** Debug app ops */ protected static final boolean DEBUG_APP_OPS = Log.isLoggable(TAG + ".AO", Log.DEBUG); private static final boolean DEBUG_APP_OPS = false; // parameters of the player that affect AppOps // parameters of the player that affect AppOps protected AudioAttributes mAttributes; protected AudioAttributes mAttributes; Loading Loading @@ -94,19 +95,9 @@ public abstract class PlayerBase { IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE); IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE); mAppOps = IAppOpsService.Stub.asInterface(b); mAppOps = IAppOpsService.Stub.asInterface(b); // initialize mHasAppOpsPlayAudio // initialize mHasAppOpsPlayAudio synchronized (mLock) { updateAppOpsPlayAudio(); updateAppOpsPlayAudio_sync(); } // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed mAppOpsCallback = new IAppOpsCallback.Stub() { mAppOpsCallback = new IAppOpsCallbackWrapper(this); public void opChanged(int op, int uid, String packageName) { synchronized (mLock) { if (op == AppOpsManager.OP_PLAY_AUDIO) { updateAppOpsPlayAudio_sync(); } } } }; try { try { mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO, mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO, ActivityThread.currentPackageName(), mAppOpsCallback); ActivityThread.currentPackageName(), mAppOpsCallback); Loading @@ -114,10 +105,8 @@ public abstract class PlayerBase { mHasAppOpsPlayAudio = false; mHasAppOpsPlayAudio = false; } } try { try { if (mIPlayer == null) { newPiid = getService().trackPlayer( throw new IllegalStateException("Cannot register a player with a null mIPlayer"); new PlayerIdCard(mImplType, mAttributes, new IPlayerWrapper(this))); } newPiid = getService().trackPlayer(new PlayerIdCard(mImplType, mAttributes, mIPlayer)); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, "Error talking to audio service, player will not be tracked", e); Log.e(TAG, "Error talking to audio service, player will not be tracked", e); } } Loading Loading @@ -259,6 +248,12 @@ public abstract class PlayerBase { } } } } private void updateAppOpsPlayAudio() { synchronized (mLock) { updateAppOpsPlayAudio_sync(); } } /** /** * To be called whenever a condition that might affect audibility of this player is updated. * To be called whenever a condition that might affect audibility of this player is updated. * Must be called synchronized on mLock. * Must be called synchronized on mLock. Loading Loading @@ -405,48 +400,96 @@ public abstract class PlayerBase { abstract void playerPause(); abstract void playerPause(); abstract void playerStop(); abstract void playerStop(); //===================================================================== private static class IAppOpsCallbackWrapper extends IAppOpsCallback.Stub { private final WeakReference<PlayerBase> mWeakPB; public IAppOpsCallbackWrapper(PlayerBase pb) { mWeakPB = new WeakReference<PlayerBase>(pb); } @Override public void opChanged(int op, int uid, String packageName) { if (op == AppOpsManager.OP_PLAY_AUDIO) { if (DEBUG_APP_OPS) { Log.v(TAG, "opChanged: op=PLAY_AUDIO pack=" + packageName); } final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.updateAppOpsPlayAudio(); } } } } //===================================================================== //===================================================================== /** /** * Implementation of IPlayer for all subclasses of PlayerBase * Wrapper around an implementation of IPlayer for all subclasses of PlayerBase * that doesn't keep a strong reference on PlayerBase */ */ private IPlayer mIPlayer = new IPlayer.Stub() { private static class IPlayerWrapper extends IPlayer.Stub { private final WeakReference<PlayerBase> mWeakPB; public IPlayerWrapper(PlayerBase pb) { mWeakPB = new WeakReference<PlayerBase>(pb); } @Override @Override public void start() { public void start() { playerStart(); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.playerStart(); } } } @Override @Override public void pause() { public void pause() { playerPause(); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.playerPause(); } } } @Override @Override public void stop() { public void stop() { playerStop(); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.playerStop(); } } } @Override @Override public void setVolume(float vol) { public void setVolume(float vol) { baseSetVolume(vol, vol); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.baseSetVolume(vol, vol); } } } @Override @Override public void setPan(float pan) { public void setPan(float pan) { baseSetPan(pan); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.baseSetPan(pan); } } } @Override @Override public void setStartDelayMs(int delayMs) { public void setStartDelayMs(int delayMs) { baseSetStartDelayMs(delayMs); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.baseSetStartDelayMs(delayMs); } } } @Override @Override public void applyVolumeShaper( public void applyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation) { @NonNull VolumeShaper.Operation operation) { /* void */ playerApplyVolumeShaper(configuration, operation); final PlayerBase pb = mWeakPB.get(); if (pb != null) { pb.playerApplyVolumeShaper(configuration, operation); } } } } }; //===================================================================== //===================================================================== /** /** Loading @@ -455,8 +498,8 @@ public abstract class PlayerBase { public static class PlayerIdCard implements Parcelable { public static class PlayerIdCard implements Parcelable { public final int mPlayerType; public final int mPlayerType; public final static int AUDIO_ATTRIBUTES_NONE = 0; public static final int AUDIO_ATTRIBUTES_NONE = 0; public final static int AUDIO_ATTRIBUTES_DEFINED = 1; public static final int AUDIO_ATTRIBUTES_DEFINED = 1; public final AudioAttributes mAttributes; public final AudioAttributes mAttributes; public final IPlayer mIPlayer; public final IPlayer mIPlayer; Loading