Android 4.2 Wifi Display 之 Settings 源码分析

转载

有关核心分析请见这里~

作者: mznewfacer    时间:2012年11月27日   

所有内容都是自己的分析,现在是简单罗列代码位置及整体结构,细节的东西会慢慢充实,欢迎讨论纠正,我会及时更改。

一、简单背景

      简单背景:随着无线互联的深入,不管是蓝牙、WIFI或者各种基于此的规范不管是UPNP还是DLNA都随着用户的需求得到了很大的发展,google 自从android 4.0引入wifi direct后,又在11月份公布的android 4.2中引入了Miracast无线显示共享,其协议在此可以下载。具体的协议部分内容比较多,本人由于水平有限,就不在这里罗列协议的内容了,只附上一份架构图供大家对其有个大致的印象。

英文缩写对应如下:

HIDC: Human Interface Device Class
UIBC: User Input Back Channel
PES: Packetized Elementary Stream
HDCP: High-bandwidth Digital Content Protection
MPEG2-TS: Moving Picture Experts Group 2 Transport Stream
RTSP: Real-Time Streaming Protocol
RTP: Real-time Transport Protocol
Wi-Fi P2P: Wi-Fi Direct
TDLS: Tunneled Direct Link Setup

二、应用层简介

    好了,接下来首先来看一看android 4.2 提供了哪些与其相关的应用:

    首先,需要注意的自然是API文档中公布的 http://developer.android.com/about/versions/android-4.2.html#SecondaryDisplays

Presentation应用,在源码中路径为:development/samples/ApiDemos/src/com/example/android/apis/app/下面的两个文件
PresentationActivity.java

以及  PresentationWithMediaRouterActivity.java 。

这两个应用所使用的Presentation基类在frameworks/base/core/java/android/app/Presentation.java,可以看到其继承了dialog类,并复用了如show()以及cancel()函数。

由于官方文档已经有了关于Presentation以及MediaRouter的简要介绍,这里先不再结合framework层详细介绍,以后有机会一并再结合源码分析一下。

       简单来说,Display Manager 可以列举出可以直连显示的多个设备,MediaRouter提供了快速获得系统中用于演示(presentations)默认显示设备的方法。可以利用

frameworks/base/media/java/android/media /MediaRouter.java下的getSelectedRoute(int type){ }函数来获得当前所选择type类型的Router信息。对于PresentationWithMediaRouterActivity应用而言,

[java] view plain copy
  1. MediaRouter mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);  
  2.      MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);  
  3.  Display presentationDisplay = route != null ? route.getPresentationDisplay() : null;  
可 以看到这里传入的是ROUTE_TYPE_LIVE_VIDEO类型,供其获取已选择的route信息。之后,则是判断route信息是否为空,如果不为 空则返回被选择演示(presentation)设备。值得一提的是,该方法只对 route信息类型为ROUTE_TYPE_LIVE_VIDEO有效。

        接下来,只要将该Display对象作为自己重构的演示(Presentation)类构造函数参数传入,这样自己重构的演示就会出现在第二个显示设备上。

[java] view plain copy
  1.  mPresentation = new DemoPresentation(this, presentationDisplay);  
  2.     ...  
  3.  try {  
  4.                 mPresentation.show();  
  5.             } catch (WindowManager.InvalidDisplayException ex) {  
  6.                 Log.w(TAG, "Couldn't show presentation!  Display was removed in "  
  7.                         + "the meantime.", ex);  
  8.                 mPresentation = null;  
  9.             }  
  10.         }  
  11. ...  
[java] view plain copy
  1. private final static class DemoPresentation extends Presentation {  
  2.         ...  
  3.   
  4.         public DemoPresentation(Context context, Display display) {  
  5.             super(context, display);  
  6.         }  
  7.        ...  
  8. }  

为了进一步优化附加显示设备自定义演示UI的显示效果,你可以在<style>属性中指定相关应用主题为android:presentationTheme。

   为了在运行时检测外设显示设备的连接状态,你需要在自己的实现类中创建一个 MediaRouter.SimpleCallback的一个实例,该实例中需要自己实现 onRoutePresentationDisplayChanged() 等回调函数。当一个新的演示显示设备连接时,系统就会回调该函数,进一步其就会调用上面提到的 MediaRouter.getSelectedRoute()函数。

[java] view plain copy
  1. private final MediaRouter.SimpleCallback mMediaRouterCallback =  
  2.            new MediaRouter.SimpleCallback() {  
  3.        public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {  
  4.            updatePresentation();  
  5.        }  
  6.        public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {  
  7.            updatePresentation();  
  8.        }  
  9.        public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {  
  10.            updatePresentation();  
  11.        }  
  12.    };  


当然,使用者需要使用MediaRouter.addCallback()函数完成注册,如同在PresentationWithMediaRouterActivity应用中,

[java] view plain copy
  1. mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_LIVE_VIDEO, mMediaRouterCallback);  

这里可以简单看看调用流程,首先可以看到onRoutePresentationDisplayChanged()回调函数在MediaRouter.java会先触发dispatchRoutePresentationDisplayChanged()函数,

frameworks/base/media/java/android/media/MediaRouter.java

[java] view plain copy
  1. static void dispatchRoutePresentationDisplayChanged(RouteInfo info) {  
  2.     for (CallbackInfo cbi : sStatic.mCallbacks) {  
  3.         if ((cbi.type & info.mSupportedTypes) != 0) {  
  4.             cbi.cb.onRoutePresentationDisplayChanged(cbi.router, info);  
  5.         }  
  6.     }  
  7. }  

进一步可以看到该分发函数被用于更新演示设备的状态,并将其提供给frameworks/base/core/java/android/app/Presentation.java中注册的监听函数,

frameworks/base/media/java/android/media/MediaRouter.java

[java]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值