diff options
| author | 2017-05-09 16:19:36 -0700 | |
|---|---|---|
| committer | 2017-05-09 16:19:36 -0700 | |
| commit | aee6ee94675d56e71a42d52b16b8d8e5fa6ea3ff (patch) | |
| tree | 121d3c9f33121162953940636784b6a158e48b73 | |
| parent | cf1b224a789f8412211d22fba9551ce01e54be14 (diff) | |
IAppOpsCallback has weak reference to PlayerBase
The implementation of the IAppOpsCallback interface was an inner class
that implicitly held a strong reference to the PlayerBase
instance, preventing subclasses of PlayerBase to be GC'd.
The fix consists in making the IAppOpsCallback implementation be a static
class and hold a weak reference to PlayerBase.
Test: see bug
Bug: 35359144
Change-Id: Ic97d07dad0be2376eef160d01ff4e4a9e5ee0bcd
| -rw-r--r-- | media/java/android/media/PlayerBase.java | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java index 72be9f71d3a8..9bd93aa31abf 100644 --- a/media/java/android/media/PlayerBase.java +++ b/media/java/android/media/PlayerBase.java @@ -46,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; @@ -95,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); @@ -258,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. @@ -405,6 +401,26 @@ 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(); + } + } + } + } + + //===================================================================== /** * Wrapper around an implementation of IPlayer for all subclasses of PlayerBase * that doesn't keep a strong reference on PlayerBase @@ -482,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; |