Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa23702d authored by Vairavan Srinivasan's avatar Vairavan Srinivasan Committed by Steve Kondik
Browse files

frameworks/base: unlink death notifications of AudioFocus clients

Death notifications of AudioFocus clients isn't needed when
focus is abandoned or client is unregistered. The accumulated
death notifications causes excessive JNI references and causes
dalvik (hosting system_server) to abort the same.

CRs-Fixed: 276052

Change-Id: I3e8a6b524ca389f1f193d8299999401de5e55d07
parent 64c83584
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1492,7 +1492,7 @@ public class AudioManager {
        IAudioService service = getService();
        try {
            status = service.abandonAudioFocus(mAudioFocusDispatcher,
                    getIdForAudioFocusListener(l));
                    getIdForAudioFocusListener(l), mICallBack);
        } catch (RemoteException e) {
            Log.e(TAG, "Can't call abandonAudioFocus() from AudioService due to "+e);
        }
+64 −11
Original line number Diff line number Diff line
@@ -257,6 +257,8 @@ public class AudioService extends IAudioService.Stub {
    // List of clients having issued a SCO start request
    private ArrayList <ScoClient> mScoClients = new ArrayList <ScoClient>();

    private ArrayList <AudioFocusDeathHandler> mAudioFocusDeathHandlers = new ArrayList <AudioFocusDeathHandler>();

    // BluetoothHeadset API to control SCO connection
    private BluetoothHeadset mBluetoothHeadset;

@@ -2012,7 +2014,7 @@ public class AudioService extends IAudioService.Stub {
                synchronized(mRingingLock) {
                    mIsRinging = false;
                }
                abandonAudioFocus(null, IN_VOICE_COMM_FOCUS_ID);
                abandonAudioFocus(null, IN_VOICE_COMM_FOCUS_ID, null);
            }
        }
    };
@@ -2146,7 +2148,7 @@ public class AudioService extends IAudioService.Stub {
     * stack if necessary.
     */
    private class AudioFocusDeathHandler implements IBinder.DeathRecipient {
        private IBinder mCb; // To be notified of client's death
        private final IBinder mCb; // To be notified of client's death

        AudioFocusDeathHandler(IBinder cb) {
            mCb = cb;
@@ -2156,6 +2158,7 @@ public class AudioService extends IAudioService.Stub {
            synchronized(mAudioFocusLock) {
                Log.w(TAG, "  AudioFocus   audio focus client died");
                removeFocusStackEntryForClient(mCb);
                mAudioFocusDeathHandlers.remove(this);
            }
        }

@@ -2220,25 +2223,60 @@ public class AudioService extends IAudioService.Stub {
        // AudioService's phone state listener
        if (!IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
            // Register for client death notification
            int size = 0;
            int i = 0;
            synchronized(mAudioFocusLock) {
              size = mAudioFocusDeathHandlers.size();
              for (i = 0; i < size; i++) {
                   final AudioFocusDeathHandler afdhandler = mAudioFocusDeathHandlers.get(i);

                   if(afdhandler.getBinder() == cb) {
                      break;
                   }
              }
            }
            // Register once per client
            if (i == size) {
                AudioFocusDeathHandler afdh = new AudioFocusDeathHandler(cb);

                try {
                    cb.linkToDeath(afdh, 0);
                    synchronized(mAudioFocusLock) {
                       mAudioFocusDeathHandlers.add(afdh);
                    }
                } catch (RemoteException e) {
                    // client has already died!
                    Log.w(TAG, "AudioFocus  requestAudioFocus() could not link to "+cb+" binder death");
                }
            }
        }

        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
    }

    /** @see AudioManager#abandonAudioFocus(IAudioFocusDispatcher) */
    public int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId) {
    public int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId, IBinder cb) {
        Log.i(TAG, " AudioFocus  abandonAudioFocus() from " + clientId);
        try {
            // this will take care of notifying the new focus owner if needed
            synchronized(mAudioFocusLock) {
                removeFocusStackEntry(clientId, true);

                if (!IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {

                    int size = mAudioFocusDeathHandlers.size();

                    for (int i = 0; i < size; i++) {

                         final AudioFocusDeathHandler afdh = mAudioFocusDeathHandlers.get(i);

                         if (cb == afdh.getBinder()) {
                             cb.unlinkToDeath(afdh ,0);
                             mAudioFocusDeathHandlers.remove(i);
                             break;
                         }
                    }
                }
            }
        } catch (java.util.ConcurrentModificationException cme) {
            // Catching this exception here is temporary. It is here just to prevent
@@ -2252,12 +2290,27 @@ public class AudioService extends IAudioService.Stub {
    }


    public void unregisterAudioFocusClient(String clientId) {
    public void unregisterAudioFocusClient(String clientId, IBinder cb) {
        synchronized(mAudioFocusLock) {
            removeFocusStackEntry(clientId, false);

            if (!IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {

                int size = mAudioFocusDeathHandlers.size();

                for (int i = 0; i < size; i++) {

                     final AudioFocusDeathHandler afdh = mAudioFocusDeathHandlers.get(i);

                     if (cb == afdh.getBinder()) {
                         cb.unlinkToDeath(afdh ,0);
                         mAudioFocusDeathHandlers.remove(i);
                         break;
                     }
                }
            }
        }
    }


    //==========================================================================================
    // RemoteControl
+3 −3
Original line number Diff line number Diff line
@@ -75,9 +75,9 @@ interface IAudioService {
    int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb, IAudioFocusDispatcher l,
            String clientId);

    int abandonAudioFocus(IAudioFocusDispatcher l, String clientId);
    int abandonAudioFocus(IAudioFocusDispatcher l, String clientId, IBinder cb);

    void unregisterAudioFocusClient(String clientId);
    void unregisterAudioFocusClient(String clientId, IBinder cb);

    void registerMediaButtonEventReceiver(in ComponentName eventReceiver);