wfd.cpp revision bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9
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(const char *iface) {
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(iface);
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 ip[:port]       \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:e:d")) >= 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            {
107                enableDisableRemoteDisplay(optarg);
108                exit(0);
109                break;
110            }
111
112            case 'd':
113            {
114                enableDisableRemoteDisplay(NULL);
115                exit(0);
116                break;
117            }
118
119            case '?':
120            case 'h':
121            default:
122                usage(argv[0]);
123                exit(1);
124        }
125    }
126
127#if SUPPORT_SINK
128    if (connectToPort < 0 && uri.empty()) {
129        fprintf(stderr,
130                "You need to select either source host or uri.\n");
131
132        exit(1);
133    }
134
135    if (connectToPort >= 0 && !uri.empty()) {
136        fprintf(stderr,
137                "You need to either connect to a wfd host or an rtsp url, "
138                "not both.\n");
139        exit(1);
140    }
141
142    sp<ANetworkSession> session = new ANetworkSession;
143    session->start();
144
145    sp<ALooper> looper = new ALooper;
146
147    sp<WifiDisplaySink> sink = new WifiDisplaySink(session);
148    looper->registerHandler(sink);
149
150    if (connectToPort >= 0) {
151        sink->start(connectToHost.c_str(), connectToPort);
152    } else {
153        sink->start(uri.c_str());
154    }
155
156    looper->start(true /* runOnCallingThread */);
157#endif
158
159    return 0;
160}
161