blob: a3ac8d084944df7184d5357da613e429bf433506 [file] [log] [blame]
Irfan Sheriff77ec5582012-03-22 17:01:39 -07001/*
2 * Copyright (C) 2010 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
17package com.android.server;
18
19import android.content.Context;
20import android.content.pm.PackageManager;
21import android.net.nsd.DnsSdServiceInfo;
22import android.net.nsd.DnsSdTxtRecord;
23import android.net.nsd.INsdManager;
24import android.net.nsd.NsdManager;
25import android.os.Binder;
26import android.os.Handler;
27import android.os.HandlerThread;
28import android.os.Message;
29import android.os.Messenger;
30import android.os.IBinder;
31import android.util.Slog;
32
33import java.io.FileDescriptor;
34import java.io.PrintWriter;
Irfan Sheriffe8de2462012-04-11 14:52:19 -070035import java.net.InetAddress;
Irfan Sheriff77ec5582012-03-22 17:01:39 -070036import java.util.ArrayList;
Irfan Sheriffe8de2462012-04-11 14:52:19 -070037import java.util.HashMap;
Irfan Sheriff77ec5582012-03-22 17:01:39 -070038import java.util.List;
Irfan Sheriffe8de2462012-04-11 14:52:19 -070039import java.util.concurrent.CountDownLatch;
Irfan Sheriff77ec5582012-03-22 17:01:39 -070040
41import com.android.internal.app.IBatteryStats;
42import com.android.internal.telephony.TelephonyIntents;
43import com.android.internal.util.AsyncChannel;
44import com.android.server.am.BatteryStatsService;
45import com.android.server.NativeDaemonConnector.Command;
46import com.android.internal.R;
47
48/**
49 * Network Service Discovery Service handles remote service discovery operation requests by
50 * implementing the INsdManager interface.
51 *
52 * @hide
53 */
54public class NsdService extends INsdManager.Stub {
55 private static final String TAG = "NsdService";
56 private static final String MDNS_TAG = "mDnsConnector";
57
58 private static final boolean DBG = true;
59
60 private Context mContext;
61
62 /**
63 * Clients receiving asynchronous messages
64 */
Irfan Sheriffe8de2462012-04-11 14:52:19 -070065 private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>();
Irfan Sheriff77ec5582012-03-22 17:01:39 -070066
67 private AsyncChannel mReplyChannel = new AsyncChannel();
68
Irfan Sheriffe8de2462012-04-11 14:52:19 -070069 private int INVALID_ID = 0;
70 private int mUniqueId = 1;
71
Irfan Sheriff77ec5582012-03-22 17:01:39 -070072 /**
73 * Handles client(app) connections
74 */
75 private class AsyncServiceHandler extends Handler {
76
77 AsyncServiceHandler(android.os.Looper looper) {
78 super(looper);
79 }
80
81 @Override
82 public void handleMessage(Message msg) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -070083 ClientInfo clientInfo;
84 DnsSdServiceInfo servInfo;
Irfan Sheriff77ec5582012-03-22 17:01:39 -070085 switch (msg.what) {
86 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
87 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
88 AsyncChannel c = (AsyncChannel) msg.obj;
89 if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
90 c.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED);
Irfan Sheriffe8de2462012-04-11 14:52:19 -070091 ClientInfo cInfo = new ClientInfo(c, msg.replyTo);
92 if (mClients.size() == 0) {
93 startMDnsDaemon();
94 }
95 mClients.put(msg.replyTo, cInfo);
Irfan Sheriff77ec5582012-03-22 17:01:39 -070096 } else {
97 Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
98 }
99 break;
100 case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
101 if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
102 Slog.e(TAG, "Send failed, client connection lost");
103 } else {
104 if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
105 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700106 mClients.remove(msg.replyTo);
107 if (mClients.size() == 0) {
108 stopMDnsDaemon();
109 }
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700110 break;
111 case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
112 AsyncChannel ac = new AsyncChannel();
113 ac.connect(mContext, this, msg.replyTo);
114 break;
115 case NsdManager.DISCOVER_SERVICES:
116 if (DBG) Slog.d(TAG, "Discover services");
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700117 servInfo = (DnsSdServiceInfo) msg.obj;
118 clientInfo = mClients.get(msg.replyTo);
119 if (clientInfo.mDiscoveryId != INVALID_ID) {
120 //discovery already in progress
121 if (DBG) Slog.d(TAG, "discovery in progress");
122 mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
123 NsdManager.ALREADY_ACTIVE);
124 break;
125 }
126 clientInfo.mDiscoveryId = getUniqueId();
127 if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
128 mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
129 } else {
130 mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
131 NsdManager.ERROR);
132 clientInfo.mDiscoveryId = INVALID_ID;
133 }
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700134 break;
135 case NsdManager.STOP_DISCOVERY:
136 if (DBG) Slog.d(TAG, "Stop service discovery");
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700137 clientInfo = mClients.get(msg.replyTo);
138 if (clientInfo.mDiscoveryId == INVALID_ID) {
139 //already stopped
140 if (DBG) Slog.d(TAG, "discovery already stopped");
141 mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
142 NsdManager.ALREADY_ACTIVE);
143 break;
144 }
145 if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
146 clientInfo.mDiscoveryId = INVALID_ID;
147 mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
148 } else {
149 mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
150 NsdManager.ERROR);
151 }
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700152 break;
153 case NsdManager.REGISTER_SERVICE:
154 if (DBG) Slog.d(TAG, "Register service");
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700155 clientInfo = mClients.get(msg.replyTo);
156 if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
157 if (DBG) Slog.d(TAG, "register service exceeds limit");
158 mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
159 NsdManager.MAX_REGS_REACHED);
160 }
161
162 int id = getUniqueId();
163 if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
164 clientInfo.mRegisteredIds.add(id);
165 } else {
166 mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
167 NsdManager.ERROR);
168 }
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700169 break;
170 case NsdManager.UPDATE_SERVICE:
171 if (DBG) Slog.d(TAG, "Update service");
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700172 //TODO: implement
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700173 mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
174 break;
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700175 case NsdManager.RESOLVE_SERVICE:
176 if (DBG) Slog.d(TAG, "Resolve service");
177 servInfo = (DnsSdServiceInfo) msg.obj;
178 clientInfo = mClients.get(msg.replyTo);
179 if (clientInfo.mResolveId != INVALID_ID) {
180 //first cancel existing resolve
181 stopResolveService(clientInfo.mResolveId);
182 }
183
184 clientInfo.mResolveId = getUniqueId();
185 if (!resolveService(clientInfo.mResolveId, servInfo)) {
186 mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
187 NsdManager.ERROR);
188 clientInfo.mResolveId = INVALID_ID;
189 }
190 break;
191 case NsdManager.STOP_RESOLVE:
192 if (DBG) Slog.d(TAG, "Stop resolve");
193 clientInfo = mClients.get(msg.replyTo);
194 if (clientInfo.mResolveId == INVALID_ID) {
195 //already stopped
196 if (DBG) Slog.d(TAG, "resolve already stopped");
197 mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
198 NsdManager.ALREADY_ACTIVE);
199 break;
200 }
201 if (stopResolveService(clientInfo.mResolveId)) {
202 clientInfo.mResolveId = INVALID_ID;
203 mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
204 } else {
205 mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
206 NsdManager.ERROR);
207 }
208 break;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700209 default:
210 Slog.d(TAG, "NsdServicehandler.handleMessage ignoring msg=" + msg);
211 break;
212 }
213 }
214 }
215 private AsyncServiceHandler mAsyncServiceHandler;
216
217 private NativeDaemonConnector mNativeConnector;
218 private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1);
219
220 private NsdService(Context context) {
221 mContext = context;
222
223 HandlerThread nsdThread = new HandlerThread("NsdService");
224 nsdThread.start();
225 mAsyncServiceHandler = new AsyncServiceHandler(nsdThread.getLooper());
226
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700227 mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10,
228 MDNS_TAG, 25);
229 Thread th = new Thread(mNativeConnector, MDNS_TAG);
230 th.start();
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700231 }
232
233 public static NsdService create(Context context) throws InterruptedException {
234 NsdService service = new NsdService(context);
235 /* service.mNativeDaemonConnected.await(); */
236 return service;
237 }
238
239 public Messenger getMessenger() {
240 return new Messenger(mAsyncServiceHandler);
241 }
242
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700243 private int getUniqueId() {
244 if (++mUniqueId == INVALID_ID) return ++mUniqueId;
245 return mUniqueId;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700246 }
247
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700248 /* These should be in sync with system/netd/mDnsResponseCode.h */
249 class NativeResponseCode {
250 public static final int SERVICE_DISCOVERY_FAILED = 602;
251 public static final int SERVICE_FOUND = 603;
252 public static final int SERVICE_LOST = 604;
253
254 public static final int SERVICE_REGISTRATION_FAILED = 605;
255 public static final int SERVICE_REGISTERED = 606;
256
257 public static final int SERVICE_RESOLUTION_FAILED = 607;
258 public static final int SERVICE_RESOLVED = 608;
259
260 public static final int SERVICE_UPDATED = 609;
261 public static final int SERVICE_UPDATE_FAILED = 610;
262
263 public static final int SERVICE_GET_ADDR_FAILED = 611;
264 public static final int SERVICE_GET_ADDR_SUCCESS = 612;
265 }
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700266
267 class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
268 public void onDaemonConnected() {
269 mNativeDaemonConnected.countDown();
270 }
271
272 public boolean onEvent(int code, String raw, String[] cooked) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700273 ClientInfo clientInfo;
274 DnsSdServiceInfo servInfo;
275 int id = Integer.parseInt(cooked[1]);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700276 switch (code) {
277 case NativeResponseCode.SERVICE_FOUND:
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700278 /* NNN uniqueId serviceName regType domain */
279 if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
280 clientInfo = getClientByDiscovery(id);
281 if (clientInfo == null) break;
282
283 servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
284 clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, servInfo);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700285 break;
286 case NativeResponseCode.SERVICE_LOST:
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700287 /* NNN uniqueId serviceName regType domain */
288 if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
289 clientInfo = getClientByDiscovery(id);
290 if (clientInfo == null) break;
291
292 servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
293 clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, servInfo);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700294 break;
295 case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
296 /* NNN uniqueId errorCode */
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700297 if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
298 clientInfo = getClientByDiscovery(id);
299 if (clientInfo == null) break;
300
301 clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
302 NsdManager.ERROR);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700303 break;
304 case NativeResponseCode.SERVICE_REGISTERED:
305 /* NNN regId serviceName regType */
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700306 if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
307 clientInfo = getClientByRegistration(id);
308 if (clientInfo == null) break;
309
310 servInfo = new DnsSdServiceInfo(cooked[2], null, null);
311 clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
312 id, 0, servInfo);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700313 break;
314 case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
315 /* NNN regId errorCode */
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700316 if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
317 clientInfo = getClientByRegistration(id);
318 if (clientInfo == null) break;
319
320 clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
321 NsdManager.ERROR);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700322 break;
323 case NativeResponseCode.SERVICE_UPDATED:
324 /* NNN regId */
325 break;
326 case NativeResponseCode.SERVICE_UPDATE_FAILED:
327 /* NNN regId errorCode */
328 break;
329 case NativeResponseCode.SERVICE_RESOLVED:
330 /* NNN resolveId fullName hostName port txtlen txtdata */
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700331 if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
332 clientInfo = getClientByResolve(id);
333 if (clientInfo == null) break;
334
335 int index = cooked[2].indexOf(".");
336 if (index == -1) {
337 Slog.e(TAG, "Invalid service found " + raw);
338 break;
339 }
340 String name = cooked[2].substring(0, index);
341 String rest = cooked[2].substring(index);
342 String type = rest.replace(".local.", "");
343
344 clientInfo.mResolvedService = new DnsSdServiceInfo(name, type, null);
345 clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
346
347 stopResolveService(id);
348 getAddrInfo(id, cooked[3]);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700349 break;
350 case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700351 case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
352 /* NNN resolveId errorCode */
353 if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
354 clientInfo = getClientByResolve(id);
355 if (clientInfo == null) break;
356
357 clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
358 NsdManager.ERROR);
359 break;
360 case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
361 /* NNN resolveId hostname ttl addr */
362 if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
363 clientInfo = getClientByResolve(id);
364 if (clientInfo == null || clientInfo.mResolvedService == null) break;
365
366 try {
367 clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
368 clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
369 clientInfo.mResolvedService);
370 clientInfo.mResolvedService = null;
371 clientInfo.mResolveId = INVALID_ID;
372 } catch (java.net.UnknownHostException e) {
373 clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
374 NsdManager.ERROR);
375 }
376 stopGetAddrInfo(id);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700377 break;
378 default:
379 break;
380 }
381 return false;
382 }
383 }
384
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700385 private boolean startMDnsDaemon() {
386 if (DBG) Slog.d(TAG, "startMDnsDaemon");
387 try {
388 mNativeConnector.execute("mdnssd", "start-service");
389 } catch(NativeDaemonConnectorException e) {
390 Slog.e(TAG, "Failed to start daemon" + e);
391 return false;
392 }
393 return true;
394 }
395
396 private boolean stopMDnsDaemon() {
397 if (DBG) Slog.d(TAG, "stopMDnsDaemon");
398 try {
399 mNativeConnector.execute("mdnssd", "stop-service");
400 } catch(NativeDaemonConnectorException e) {
401 Slog.e(TAG, "Failed to start daemon" + e);
402 return false;
403 }
404 return true;
405 }
406
407 private boolean registerService(int regId, DnsSdServiceInfo service) {
408 if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700409 try {
410 //Add txtlen and txtdata
411 mNativeConnector.execute("mdnssd", "register", regId, service.getServiceName(),
412 service.getServiceType(), service.getPort());
413 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700414 Slog.e(TAG, "Failed to execute registerService " + e);
415 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700416 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700417 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700418 }
419
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700420 private boolean unregisterService(int regId) {
421 if (DBG) Slog.d(TAG, "unregisterService: " + regId);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700422 try {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700423 mNativeConnector.execute("mdnssd", "stop-register", regId);
424 } catch(NativeDaemonConnectorException e) {
425 Slog.e(TAG, "Failed to execute unregisterService " + e);
426 return false;
427 }
428 return true;
429 }
430
431 private boolean updateService(int regId, DnsSdTxtRecord t) {
432 if (DBG) Slog.d(TAG, "updateService: " + regId + " " + t);
433 try {
434 if (t == null) return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700435 mNativeConnector.execute("mdnssd", "update", regId, t.size(), t.getRawData());
436 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700437 Slog.e(TAG, "Failed to updateServices " + e);
438 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700439 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700440 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700441 }
442
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700443 private boolean discoverServices(int discoveryId, String serviceType) {
444 if (DBG) Slog.d(TAG, "discoverServices: " + discoveryId + " " + serviceType);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700445 try {
446 mNativeConnector.execute("mdnssd", "discover", discoveryId, serviceType);
447 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700448 Slog.e(TAG, "Failed to discoverServices " + e);
449 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700450 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700451 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700452 }
453
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700454 private boolean stopServiceDiscovery(int discoveryId) {
455 if (DBG) Slog.d(TAG, "stopServiceDiscovery: " + discoveryId);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700456 try {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700457 mNativeConnector.execute("mdnssd", "stop-discover", discoveryId);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700458 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700459 Slog.e(TAG, "Failed to stopServiceDiscovery " + e);
460 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700461 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700462 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700463 }
464
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700465 private boolean resolveService(int resolveId, DnsSdServiceInfo service) {
466 if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700467 try {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700468 mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(),
469 service.getServiceType(), "local.");
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700470 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700471 Slog.e(TAG, "Failed to resolveService " + e);
472 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700473 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700474 return true;
475 }
476
477 private boolean stopResolveService(int resolveId) {
478 if (DBG) Slog.d(TAG, "stopResolveService: " + resolveId);
479 try {
480 mNativeConnector.execute("mdnssd", "stop-resolve", resolveId);
481 } catch(NativeDaemonConnectorException e) {
482 Slog.e(TAG, "Failed to stop resolve " + e);
483 return false;
484 }
485 return true;
486 }
487
488 private boolean getAddrInfo(int resolveId, String hostname) {
489 if (DBG) Slog.d(TAG, "getAdddrInfo: " + resolveId);
490 try {
491 mNativeConnector.execute("mdnssd", "getaddrinfo", resolveId, hostname);
492 } catch(NativeDaemonConnectorException e) {
493 Slog.e(TAG, "Failed to getAddrInfo " + e);
494 return false;
495 }
496 return true;
497 }
498
499 private boolean stopGetAddrInfo(int resolveId) {
500 if (DBG) Slog.d(TAG, "stopGetAdddrInfo: " + resolveId);
501 try {
502 mNativeConnector.execute("mdnssd", "stop-getaddrinfo", resolveId);
503 } catch(NativeDaemonConnectorException e) {
504 Slog.e(TAG, "Failed to stopGetAddrInfo " + e);
505 return false;
506 }
507 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700508 }
509
510 @Override
511 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
512 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
513 != PackageManager.PERMISSION_GRANTED) {
514 pw.println("Permission Denial: can't dump ServiceDiscoverService from from pid="
515 + Binder.getCallingPid()
516 + ", uid=" + Binder.getCallingUid());
517 return;
518 }
519
520 pw.println("Internal state:");
521 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700522
523 private ClientInfo getClientByDiscovery(int discoveryId) {
524 for (ClientInfo c: mClients.values()) {
525 if (c.mDiscoveryId == discoveryId) {
526 return c;
527 }
528 }
529 return null;
530 }
531
532 private ClientInfo getClientByResolve(int resolveId) {
533 for (ClientInfo c: mClients.values()) {
534 if (c.mResolveId == resolveId) {
535 return c;
536 }
537 }
538 return null;
539 }
540
541 private ClientInfo getClientByRegistration(int regId) {
542 for (ClientInfo c: mClients.values()) {
543 if (c.mRegisteredIds.contains(regId)) {
544 return c;
545 }
546 }
547 return null;
548 }
549
550 /* Information tracked per client */
551 private class ClientInfo {
552
553 private static final int MAX_REG = 5;
554 private AsyncChannel mChannel;
555 private Messenger mMessenger;
556 private int mDiscoveryId;
557 private int mResolveId;
558 /* Remembers a resolved service until getaddrinfo completes */
559 private DnsSdServiceInfo mResolvedService;
560 private ArrayList<Integer> mRegisteredIds = new ArrayList<Integer>();
561
562 private ClientInfo(AsyncChannel c, Messenger m) {
563 mChannel = c;
564 mMessenger = m;
565 mDiscoveryId = mResolveId = INVALID_ID;
566 if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m);
567 }
568 }
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700569}