diff options
| -rw-r--r-- | media/java/android/media/PlayerBase.java | 105 |
1 files changed, 74 insertions, 31 deletions
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java index dd666493c346..9bd93aa31abf 100644 --- a/media/java/android/media/PlayerBase.java +++ b/media/java/android/media/PlayerBase.java @@ -35,6 +35,7 @@ import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import java.lang.IllegalArgumentException; +import java.lang.ref.WeakReference; import java.util.Objects; /** @@ -45,11 +46,11 @@ import java.util.Objects; */ public abstract class PlayerBase { - private final static String TAG = "PlayerBase"; - private final static boolean DEBUG = false; + private static final String TAG = "PlayerBase"; + private static final boolean DEBUG = false; private static IAudioService sService; //lazy initialization, use getService() /** 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 protected AudioAttributes mAttributes; @@ -94,19 +95,9 @@ public abstract class PlayerBase { IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE); mAppOps = IAppOpsService.Stub.asInterface(b); // initialize mHasAppOpsPlayAudio - synchronized (mLock) { - updateAppOpsPlayAudio_sync(); - } + updateAppOpsPlayAudio(); // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed - mAppOpsCallback = new IAppOpsCallback.Stub() { - public void opChanged(int op, int uid, String packageName) { - synchronized (mLock) { - if (op == AppOpsManager.OP_PLAY_AUDIO) { - updateAppOpsPlayAudio_sync(); - } - } - } - }; + mAppOpsCallback = new IAppOpsCallbackWrapper(this); try { mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO, ActivityThread.currentPackageName(), mAppOpsCallback); @@ -114,10 +105,8 @@ public abstract class PlayerBase { mHasAppOpsPlayAudio = false; } try { - if (mIPlayer == null) { - throw new IllegalStateException("Cannot register a player with a null mIPlayer"); - } - newPiid = getService().trackPlayer(new PlayerIdCard(mImplType, mAttributes, mIPlayer)); + newPiid = getService().trackPlayer( + new PlayerIdCard(mImplType, mAttributes, new IPlayerWrapper(this))); } catch (RemoteException e) { Log.e(TAG, "Error talking to audio service, player will not be tracked", e); } @@ -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. * Must be called synchronized on mLock. @@ -406,47 +401,95 @@ public abstract class PlayerBase { 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 public void start() { - playerStart(); + final PlayerBase pb = mWeakPB.get(); + if (pb != null) { + pb.playerStart(); + } } @Override public void pause() { - playerPause(); + final PlayerBase pb = mWeakPB.get(); + if (pb != null) { + pb.playerPause(); + } } @Override public void stop() { - playerStop(); + final PlayerBase pb = mWeakPB.get(); + if (pb != null) { + pb.playerStop(); + } } @Override public void setVolume(float vol) { - baseSetVolume(vol, vol); + final PlayerBase pb = mWeakPB.get(); + if (pb != null) { + pb.baseSetVolume(vol, vol); + } } @Override public void setPan(float pan) { - baseSetPan(pan); + final PlayerBase pb = mWeakPB.get(); + if (pb != null) { + pb.baseSetPan(pan); + } } @Override public void setStartDelayMs(int delayMs) { - baseSetStartDelayMs(delayMs); + final PlayerBase pb = mWeakPB.get(); + if (pb != null) { + pb.baseSetStartDelayMs(delayMs); + } } @Override public void applyVolumeShaper( @NonNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation) { - /* void */ playerApplyVolumeShaper(configuration, operation); + final PlayerBase pb = mWeakPB.get(); + if (pb != null) { + pb.playerApplyVolumeShaper(configuration, operation); + } } - }; + } //===================================================================== /** @@ -455,8 +498,8 @@ public abstract class PlayerBase { public static class PlayerIdCard implements Parcelable { public final int mPlayerType; - public final static int AUDIO_ATTRIBUTES_NONE = 0; - public final static int AUDIO_ATTRIBUTES_DEFINED = 1; + public static final int AUDIO_ATTRIBUTES_NONE = 0; + public static final int AUDIO_ATTRIBUTES_DEFINED = 1; public final AudioAttributes mAttributes; public final IPlayer mIPlayer; |