前言

接上回《简单跟一下MediaSession源码1》,介绍到onMediaButtonSessionChanged(),今天继续跟一下。记录于此,方便自己查阅。

虽然写着是MediaSession,但记录的是MediaSessionService的代码。

这篇就是继续上一篇的流程,意义不大,不推荐看!

已经放弃,记录于此只是自己的过程。

正文

MediaSessionService.java

frameworks\base\services\core\java\com\android\server\media\MediaSessionService.java

上次说到的FullUserRecord.onMediaButtonSessionChanged()是在MediaSessionService.java定义的。

oldMediaButtonSession

FullUserRecord.onMediaButtonSessionChanged()
@Override
public void onMediaButtonSessionChanged(MediaSessionRecordImpl oldMediaButtonSession,
        MediaSessionRecordImpl newMediaButtonSession) {
    synchronized (mLock) {
        if (oldMediaButtonSession != null) {
            mHandler.postSessionsChanged(oldMediaButtonSession);
        }
        if (newMediaButtonSession != null) {
            //保存MediaButton的接收者
            rememberMediaButtonReceiverLocked(newMediaButtonSession);
            mHandler.postSessionsChanged(newMediaButtonSession);
        }
        pushAddressedPlayerChangedLocked();
    }
}

如果是第一次注册MediaButton监听,oldMediaButtonSession是为null的。

下面分别重点跟一下:

  1. rememberMediaButtonReceiverLocked

  2. postSessionsChanged()

rememberMediaButtonReceiverLocked()
// Remember media button receiver and keep it in the persistent storage.
public void rememberMediaButtonReceiverLocked(MediaSessionRecordImpl record) {
    if (record instanceof MediaSession2Record) {
        return;
    }
    MediaSessionRecord sessionRecord = (MediaSessionRecord) record;
    mLastMediaButtonReceiverHolder = sessionRecord.getMediaButtonReceiver();
    String mediaButtonReceiverInfo = (mLastMediaButtonReceiverHolder == null)
            ? "" : mLastMediaButtonReceiverHolder.flattenToString();
    //保存到Settings中
    Settings.Secure.putString(mContentResolver,
            MEDIA_BUTTON_RECEIVER,
            mediaButtonReceiverInfo);
}
MessageHandler.postSessionsChanged()
public void postSessionsChanged(MediaSessionRecordImpl record) {
    Integer userIdInteger = mIntegerCache.get(record.getUserId());
    if (userIdInteger == null) {
        userIdInteger = Integer.valueOf(record.getUserId());
        mIntegerCache.put(record.getUserId(), userIdInteger);
    }
    //发送MSG_SESSIONS_1_CHANGED
    //上面传入的是MediaSessionRecord对象
    int msg = (record instanceof MediaSessionRecord)
            ? MSG_SESSIONS_1_CHANGED : MSG_SESSIONS_2_CHANGED;
    removeMessages(msg, userIdInteger);
    obtainMessage(msg, userIdInteger).sendToTarget();
}
MessageHandler.handleMessage()
@Override
public void handleMessage(Message msg) {
    switch (msg.what) {
        case MSG_SESSIONS_1_CHANGED:
            //看这里。
            pushSession1Changed((int) msg.obj);
            break;
        case MSG_SESSIONS_2_CHANGED:
            pushSession2Changed((int) msg.obj);
            break;
    }
}
pushSession1Changed()
private void pushSession1Changed(int userId) {
    synchronized (mLock) {
        //获取当前用户所有FullUserRecord
        FullUserRecord user = getFullUserRecordLocked(userId);
        if (user == null) {
            return;
        }
        //获取当前用户所有MediaSessionRecord ,关注一下
        List<MediaSessionRecord> records = getActiveSessionsLocked(userId);
        int size = records.size();
        ArrayList<MediaSession.Token> tokens = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            tokens.add(records.get(i).getSessionToken());
        }
        pushRemoteVolumeUpdateLocked(userId);
        //遍历所有mSessionsListeners
        for (int i = mSessionsListeners.size() - 1; i >= 0; i--) {
            //获取SessionsListenerRecord对象
            SessionsListenerRecord record = mSessionsListeners.get(i);
            if (record.userId == ALL.getIdentifier() || record.userId == userId) {
                try {
                    //匹配,通知变化
                    record.listener.onActiveSessionsChanged(tokens);
                } catch (RemoteException e) {
                    mSessionsListeners.remove(i);
                }
            }
        }
    }
}

这里先关注一下

  1. getActiveSessionsLocked()获取所有需要通知的Sessions

  2. record.listener.onActiveSessionsChanged(tokens)通知变化。

getActiveSessionsLocked()
private List<MediaSessionRecord> getActiveSessionsLocked(int userId) {
    List<MediaSessionRecord> records = new ArrayList<>();
    //不相等,走else
    if (userId == ALL.getIdentifier()) {
        int size = mUserRecords.size();
        for (int i = 0; i < size; i++) {
            records.addAll(mUserRecords.valueAt(i).mPriorityStack.getActiveSessions(userId));
        }
    } else {
        FullUserRecord user = getFullUserRecordLocked(userId);
        if (user == null) {
            return records;
        }
        //获取active的Sessions
        records.addAll(user.mPriorityStack.getActiveSessions(userId));
    }
    // Return global priority session at the first whenever it's asked.
    //判断是否有符合的全局Session
    if (isGlobalPriorityActiveLocked()
            && (userId == ALL.getIdentifier()
                    || userId == mGlobalPrioritySession.getUserId())) {
        //全局的优先级高,优先处理
        records.add(0, mGlobalPrioritySession);
    }
    return records;
}

这里简单看一下满足isGlobalPriorityActiveLocked()的条件。

isGlobalPriorityActiveLocked()
private boolean isGlobalPriorityActiveLocked() {
    return  mGlobalPrioritySession != null && mGlobalPrioritySession.isActive();
}

MediaSessionRecord.java

frameworks\base\services\core\java\com\android\server\media\MediaSessionRecord.java

isActive()在MediaSessionRecord.java中定义。

isActive()

满足mIsActive为true,同时没有进入销毁状态

@Override
public boolean isActive() {
    return mIsActive && !mDestroyed;
}
setActive()
@Override
public void setActive(boolean active) throws RemoteException {
    mIsActive = active;
    final long token = Binder.clearCallingIdentity();
    try {
        mService.onSessionActiveStateChanged(MediaSessionRecord.this);
    } finally {
        Binder.restoreCallingIdentity(token);
    }
    //通知MSG_UPDATE_SESSION_STATE,但没有做任何事,已经被丢弃
    mHandler.post(MessageHandler.MSG_UPDATE_SESSION_STATE);
}
close()
 @Override
 public void close() {
     synchronized (mLock) {
         if (mDestroyed) {
             return;
         }
         mSessionCb.mCb.asBinder().unlinkToDeath(this, 0);
         mDestroyed = true;
         mPlaybackState = null;
         mHandler.post(MessageHandler.MSG_DESTROYED);
     }
 }

mDestroyed这个状态在MediaSessionRecord.java比较重要,很多消息的更新都要判断这个。

MediaSessionService.java

回到pushSession1Changed()中看

record.listener.onActiveSessionsChanged(tokens);

record的是对象,而且是从mSessionsListeners中获取的

SessionsListenerRecord record = mSessionsListeners.get(i);

我们看SessionsListenerRecord什么时候添加和移除的。

SessionManagerImpl.addSessionsListener()
@Override
public void addSessionsListener(IActiveSessionsListener listener,
        ComponentName componentName, int userId) throws RemoteException {
    if (listener == null) {
        return;
    }
    final int pid = Binder.getCallingPid();
    final int uid = Binder.getCallingUid();
    final long token = Binder.clearCallingIdentity();
    try {
        int resolvedUserId = verifySessionsRequest(componentName, userId, pid, uid);
        synchronized (mLock) {
            int index = findIndexOfSessionsListenerLocked(listener);
            if (index != -1) {
                return;
            }
            //根据包名等信息创建SessionsListenerRecord
            SessionsListenerRecord record = new SessionsListenerRecord(listener,
                    componentName, resolvedUserId, pid, uid);
            try {
                listener.asBinder().linkToDeath(record, 0);
            } catch (RemoteException e) {
                return;
            }
            mSessionsListeners.add(record);
        }
    } finally {
        Binder.restoreCallingIdentity(token);
    }
}
SessionManagerImpl.removeSessionsListener()
@Override
public void removeSessionsListener(IActiveSessionsListener listener)
        throws RemoteException {
    synchronized (mLock) {
        int index = findIndexOfSessionsListenerLocked(listener);
        if (index != -1) {
            //这里移除
            SessionsListenerRecord record = mSessionsListeners.remove(index);
            try {
                record.listener.asBinder().unlinkToDeath(record, 0);
            } catch (Exception e) {
            }
        }
    }
}

对于SessionManagerImpl,前面《简单跟一下MediaSession源码1》有介绍过。

这里总结一下,SessionManagerImpl是MediaSessionManager代理服务类。因此,上面添加和移除是MediaSessionManager中添加的。

参考文章

相关文章

暂无评论

none
暂无评论...