wfd.cpp revision d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480c
1/* 2 * Copyright 2012, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "wfd" 19#include <utils/Log.h> 20 21#define SUPPORT_SINK 0 22 23#if SUPPORT_SINK 24#include "sink/WifiDisplaySink.h" 25#endif 26 27#include <binder/ProcessState.h> 28#include <binder/IServiceManager.h> 29#include <media/IMediaPlayerService.h> 30#include <media/stagefright/DataSource.h> 31#include <media/stagefright/foundation/ADebug.h> 32 33namespace android { 34 35static void enableDisableRemoteDisplay(bool enable) { 36 sp<IServiceManager> sm = defaultServiceManager(); 37 sp<IBinder> binder = sm->getService(String16("media.player")); 38 39 sp<IMediaPlayerService> service = 40 interface_cast<IMediaPlayerService>(binder); 41 42 CHECK(service.get() != NULL); 43 44 service->enableRemoteDisplay(enable); 45} 46 47} // namespace android 48 49static void usage(const char *me) { 50 fprintf(stderr, 51 "usage:\n" 52#if SUPPORT_SINK 53 " %s -c host[:port]\tconnect to wifi source\n" 54 " -u uri \tconnect to an rtsp uri\n" 55#endif 56 " -e \tenable remote display\n" 57 " -d \tdisable remote display\n", 58 me); 59} 60 61int main(int argc, char **argv) { 62 using namespace android; 63 64 ProcessState::self()->startThreadPool(); 65 66 DataSource::RegisterDefaultSniffers(); 67 68 AString connectToHost; 69 int32_t connectToPort = -1; 70 AString uri; 71 72 int res; 73 while ((res = getopt(argc, argv, "hc:l:u:ed")) >= 0) { 74 switch (res) { 75#if SUPPORT_SINK 76 case 'c': 77 { 78 const char *colonPos = strrchr(optarg, ':'); 79 80 if (colonPos == NULL) { 81 connectToHost = optarg; 82 connectToPort = WifiDisplaySource::kWifiDisplayDefaultPort; 83 } else { 84 connectToHost.setTo(optarg, colonPos - optarg); 85 86 char *end; 87 connectToPort = strtol(colonPos + 1, &end, 10); 88 89 if (*end != '\0' || end == colonPos + 1 90 || connectToPort < 1 || connectToPort > 65535) { 91 fprintf(stderr, "Illegal port specified.\n"); 92 exit(1); 93 } 94 } 95 break; 96 } 97 98 case 'u': 99 { 100 uri = optarg; 101 break; 102 } 103#endif 104 105 case 'e': 106 case 'd': 107 { 108 enableDisableRemoteDisplay(res == 'e'); 109 exit(0); 110 break; 111 } 112 113 case '?': 114 case 'h': 115 default: 116 usage(argv[0]); 117 exit(1); 118 } 119 } 120 121#if SUPPORT_SINK 122 if (connectToPort < 0 && uri.empty()) { 123 fprintf(stderr, 124 "You need to select either source host or uri.\n"); 125 126 exit(1); 127 } 128 129 if (connectToPort >= 0 && !uri.empty()) { 130 fprintf(stderr, 131 "You need to either connect to a wfd host or an rtsp url, " 132 "not both.\n"); 133 exit(1); 134 } 135 136 sp<ANetworkSession> session = new ANetworkSession; 137 session->start(); 138 139 sp<ALooper> looper = new ALooper; 140 141 sp<WifiDisplaySink> sink = new WifiDisplaySink(session); 142 looper->registerHandler(sink); 143 144 if (connectToPort >= 0) { 145 sink->start(connectToHost.c_str(), connectToPort); 146 } else { 147 sink->start(uri.c_str()); 148 } 149 150 looper->start(true /* runOnCallingThread */); 151#endif 152 153 return 0; 154} 155