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