Android Wifi Display相关的底层逻辑主要在下面这个文件中实现:frameworks/av/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
下面的函数通过接收各种消息来处理不同的逻辑
void WifiDisplaySource::onMessageReceived(const sp &msg) {
}
截图如下。我们重点分析下kWhatPlaybackSessionNotify。
其余的主要是初始化状态,根据系统设置,选择同屏的分辨率,依旧刷新率。
kWhatPlaybackSessionNotify主要是是建立同sink的会话机制
case kWhatPlaybackSessionNotify:
{
…
if (what == PlaybackSession::kWhatSessionDead) {
…
} else if (what == PlaybackSession::kWhatSessionEstablished) {
…
if (mClient != NULL) {
…
//获取初始化的WFD分辨率、使用的协议等
CHECK(VideoFormats::GetConfiguration(
mChosenVideoResolutionType,
mChosenVideoResolutionIndex,
&width,
&height,
NULL ,
NULL ));
//通知WFD已经建立connect。最终调用 frameworks/base/core/jni/android_media_RemoteDisplay.cpp里面的onDisplayConnected
mClient->onDisplayConnected(
mClientInfo.mPlaybackSession
->getSurfaceTexture(),
width,
height,
mUsingHDCP
? IRemoteDisplayClient::kDisplayFlagSecure
: 0,
playbackSessionID);
}
}
frameworks/base/core/jni/android_media_RemoteDisplay.cpp
virtual void onDisplayConnected(const sp& bufferProducer,
uint32_t width, uint32_t height, uint32_t flags, uint32_t session) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
jobject surfaceObj = android_view_Surface_createFromIGraphicBufferProducer(env, bufferProducer);
if (surfaceObj == NULL) {
ALOGE("Could not create Surface from surface texture %p provided by media server.",
bufferProducer.get());
return;
}
ALOGE(" Surface from surface texture provided by media server.");
//调用
env->CallVoidMethod(mRemoteDisplayObjGlobal,
//通过jni调用 WifiDisplayAdapter gRemoteDisplayClassInfo.notifyDisplayConnected,
surfaceObj, width, height, flags, session);
env->DeleteLocalRef(surfaceObj);
checkAndClearExceptionFromCallback(env, “notifyDisplayConnected”);
}
最终会调用frameworks/base/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@Override
public void onDisplayConnected(WifiDisplay display, Surface surface,
int width, int height, int flags) {
synchronized (getSyncRoot()) {
///M:@{ WFD Sink Support
if (mSinkEnabled) {
handleSinkEvent(display, SinkEvent.SINK_EVENT_CONNECTED);
return;
}
///@}
display = mPersistentDataStore.applyWifiDisplayAlias(display);
addDisplayDeviceLocked(display, surface, width, height, flags);
if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTED
|| mActiveDisplay == null
|| !mActiveDisplay.equals(display)) {
mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_CONNECTED;
mActiveDisplay = display;
scheduleStatusChangedBroadcastLocked();
}
}
}
通过addDisplayDeviceLocked 就可以将surface绑定到 Wifi Display服务中。
我们可以对surface进行各种操作。进一步连接欢迎加QQ: 409259564