blob: 8014e272b093cb40650ec82b972bc29e87c1e3c9 [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;
Irfan Sheriff18da1322012-04-13 12:15:41 -0700170 case NsdManager.UNREGISTER_SERVICE:
171 if (DBG) Slog.d(TAG, "unregister service");
172 clientInfo = mClients.get(msg.replyTo);
173 int regId = msg.arg1;
174 if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
175 unregisterService(regId)) {
176 mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
177 } else {
178 mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
179 NsdManager.ERROR);
180 }
181 break;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700182 case NsdManager.UPDATE_SERVICE:
183 if (DBG) Slog.d(TAG, "Update service");
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700184 //TODO: implement
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700185 mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
186 break;
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700187 case NsdManager.RESOLVE_SERVICE:
188 if (DBG) Slog.d(TAG, "Resolve service");
189 servInfo = (DnsSdServiceInfo) msg.obj;
190 clientInfo = mClients.get(msg.replyTo);
191 if (clientInfo.mResolveId != INVALID_ID) {
192 //first cancel existing resolve
193 stopResolveService(clientInfo.mResolveId);
194 }
195
196 clientInfo.mResolveId = getUniqueId();
197 if (!resolveService(clientInfo.mResolveId, servInfo)) {
198 mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
199 NsdManager.ERROR);
200 clientInfo.mResolveId = INVALID_ID;
201 }
202 break;
203 case NsdManager.STOP_RESOLVE:
204 if (DBG) Slog.d(TAG, "Stop resolve");
205 clientInfo = mClients.get(msg.replyTo);
206 if (clientInfo.mResolveId == INVALID_ID) {
207 //already stopped
208 if (DBG) Slog.d(TAG, "resolve already stopped");
209 mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
210 NsdManager.ALREADY_ACTIVE);
211 break;
212 }
213 if (stopResolveService(clientInfo.mResolveId)) {
214 clientInfo.mResolveId = INVALID_ID;
215 mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
216 } else {
217 mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
218 NsdManager.ERROR);
219 }
220 break;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700221 default:
222 Slog.d(TAG, "NsdServicehandler.handleMessage ignoring msg=" + msg);
223 break;
224 }
225 }
226 }
227 private AsyncServiceHandler mAsyncServiceHandler;
228
229 private NativeDaemonConnector mNativeConnector;
230 private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1);
231
232 private NsdService(Context context) {
233 mContext = context;
234
235 HandlerThread nsdThread = new HandlerThread("NsdService");
236 nsdThread.start();
237 mAsyncServiceHandler = new AsyncServiceHandler(nsdThread.getLooper());
238
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700239 mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10,
240 MDNS_TAG, 25);
241 Thread th = new Thread(mNativeConnector, MDNS_TAG);
242 th.start();
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700243 }
244
245 public static NsdService create(Context context) throws InterruptedException {
246 NsdService service = new NsdService(context);
247 /* service.mNativeDaemonConnected.await(); */
248 return service;
249 }
250
251 public Messenger getMessenger() {
Irfan Sheriff18da1322012-04-13 12:15:41 -0700252 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
253 "NsdService");
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700254 return new Messenger(mAsyncServiceHandler);
255 }
256
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700257 private int getUniqueId() {
258 if (++mUniqueId == INVALID_ID) return ++mUniqueId;
259 return mUniqueId;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700260 }
261
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700262 /* These should be in sync with system/netd/mDnsResponseCode.h */
263 class NativeResponseCode {
264 public static final int SERVICE_DISCOVERY_FAILED = 602;
265 public static final int SERVICE_FOUND = 603;
266 public static final int SERVICE_LOST = 604;
267
268 public static final int SERVICE_REGISTRATION_FAILED = 605;
269 public static final int SERVICE_REGISTERED = 606;
270
271 public static final int SERVICE_RESOLUTION_FAILED = 607;
272 public static final int SERVICE_RESOLVED = 608;
273
274 public static final int SERVICE_UPDATED = 609;
275 public static final int SERVICE_UPDATE_FAILED = 610;
276
277 public static final int SERVICE_GET_ADDR_FAILED = 611;
278 public static final int SERVICE_GET_ADDR_SUCCESS = 612;
279 }
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700280
281 class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
282 public void onDaemonConnected() {
283 mNativeDaemonConnected.countDown();
284 }
285
286 public boolean onEvent(int code, String raw, String[] cooked) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700287 ClientInfo clientInfo;
288 DnsSdServiceInfo servInfo;
289 int id = Integer.parseInt(cooked[1]);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700290 switch (code) {
291 case NativeResponseCode.SERVICE_FOUND:
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700292 /* NNN uniqueId serviceName regType domain */
293 if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
294 clientInfo = getClientByDiscovery(id);
295 if (clientInfo == null) break;
296
297 servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
298 clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, servInfo);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700299 break;
300 case NativeResponseCode.SERVICE_LOST:
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700301 /* NNN uniqueId serviceName regType domain */
302 if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
303 clientInfo = getClientByDiscovery(id);
304 if (clientInfo == null) break;
305
306 servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
307 clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, servInfo);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700308 break;
309 case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
310 /* NNN uniqueId errorCode */
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700311 if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
312 clientInfo = getClientByDiscovery(id);
313 if (clientInfo == null) break;
314
315 clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
316 NsdManager.ERROR);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700317 break;
318 case NativeResponseCode.SERVICE_REGISTERED:
319 /* NNN regId serviceName regType */
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700320 if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
321 clientInfo = getClientByRegistration(id);
322 if (clientInfo == null) break;
323
324 servInfo = new DnsSdServiceInfo(cooked[2], null, null);
325 clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
326 id, 0, servInfo);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700327 break;
328 case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
329 /* NNN regId errorCode */
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700330 if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
331 clientInfo = getClientByRegistration(id);
332 if (clientInfo == null) break;
333
334 clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
335 NsdManager.ERROR);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700336 break;
337 case NativeResponseCode.SERVICE_UPDATED:
338 /* NNN regId */
339 break;
340 case NativeResponseCode.SERVICE_UPDATE_FAILED:
341 /* NNN regId errorCode */
342 break;
343 case NativeResponseCode.SERVICE_RESOLVED:
344 /* NNN resolveId fullName hostName port txtlen txtdata */
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700345 if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
346 clientInfo = getClientByResolve(id);
347 if (clientInfo == null) break;
348
349 int index = cooked[2].indexOf(".");
350 if (index == -1) {
351 Slog.e(TAG, "Invalid service found " + raw);
352 break;
353 }
354 String name = cooked[2].substring(0, index);
355 String rest = cooked[2].substring(index);
356 String type = rest.replace(".local.", "");
357
358 clientInfo.mResolvedService = new DnsSdServiceInfo(name, type, null);
359 clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
360
361 stopResolveService(id);
362 getAddrInfo(id, cooked[3]);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700363 break;
364 case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700365 case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
366 /* NNN resolveId errorCode */
367 if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
368 clientInfo = getClientByResolve(id);
369 if (clientInfo == null) break;
370
371 clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
372 NsdManager.ERROR);
373 break;
374 case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
375 /* NNN resolveId hostname ttl addr */
376 if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
377 clientInfo = getClientByResolve(id);
378 if (clientInfo == null || clientInfo.mResolvedService == null) break;
379
380 try {
381 clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
382 clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
383 clientInfo.mResolvedService);
384 clientInfo.mResolvedService = null;
385 clientInfo.mResolveId = INVALID_ID;
386 } catch (java.net.UnknownHostException e) {
387 clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
388 NsdManager.ERROR);
389 }
390 stopGetAddrInfo(id);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700391 break;
392 default:
393 break;
394 }
395 return false;
396 }
397 }
398
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700399 private boolean startMDnsDaemon() {
400 if (DBG) Slog.d(TAG, "startMDnsDaemon");
401 try {
402 mNativeConnector.execute("mdnssd", "start-service");
403 } catch(NativeDaemonConnectorException e) {
404 Slog.e(TAG, "Failed to start daemon" + e);
405 return false;
406 }
407 return true;
408 }
409
410 private boolean stopMDnsDaemon() {
411 if (DBG) Slog.d(TAG, "stopMDnsDaemon");
412 try {
413 mNativeConnector.execute("mdnssd", "stop-service");
414 } catch(NativeDaemonConnectorException e) {
415 Slog.e(TAG, "Failed to start daemon" + e);
416 return false;
417 }
418 return true;
419 }
420
421 private boolean registerService(int regId, DnsSdServiceInfo service) {
422 if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700423 try {
424 //Add txtlen and txtdata
425 mNativeConnector.execute("mdnssd", "register", regId, service.getServiceName(),
426 service.getServiceType(), service.getPort());
427 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700428 Slog.e(TAG, "Failed to execute registerService " + e);
429 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700430 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700431 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700432 }
433
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700434 private boolean unregisterService(int regId) {
435 if (DBG) Slog.d(TAG, "unregisterService: " + regId);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700436 try {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700437 mNativeConnector.execute("mdnssd", "stop-register", regId);
438 } catch(NativeDaemonConnectorException e) {
439 Slog.e(TAG, "Failed to execute unregisterService " + e);
440 return false;
441 }
442 return true;
443 }
444
445 private boolean updateService(int regId, DnsSdTxtRecord t) {
446 if (DBG) Slog.d(TAG, "updateService: " + regId + " " + t);
447 try {
448 if (t == null) return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700449 mNativeConnector.execute("mdnssd", "update", regId, t.size(), t.getRawData());
450 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700451 Slog.e(TAG, "Failed to updateServices " + e);
452 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700453 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700454 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700455 }
456
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700457 private boolean discoverServices(int discoveryId, String serviceType) {
458 if (DBG) Slog.d(TAG, "discoverServices: " + discoveryId + " " + serviceType);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700459 try {
460 mNativeConnector.execute("mdnssd", "discover", discoveryId, serviceType);
461 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700462 Slog.e(TAG, "Failed to discoverServices " + e);
463 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700464 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700465 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700466 }
467
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700468 private boolean stopServiceDiscovery(int discoveryId) {
469 if (DBG) Slog.d(TAG, "stopServiceDiscovery: " + discoveryId);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700470 try {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700471 mNativeConnector.execute("mdnssd", "stop-discover", discoveryId);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700472 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700473 Slog.e(TAG, "Failed to stopServiceDiscovery " + e);
474 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700475 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700476 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700477 }
478
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700479 private boolean resolveService(int resolveId, DnsSdServiceInfo service) {
480 if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service);
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700481 try {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700482 mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(),
483 service.getServiceType(), "local.");
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700484 } catch(NativeDaemonConnectorException e) {
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700485 Slog.e(TAG, "Failed to resolveService " + e);
486 return false;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700487 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700488 return true;
489 }
490
491 private boolean stopResolveService(int resolveId) {
492 if (DBG) Slog.d(TAG, "stopResolveService: " + resolveId);
493 try {
494 mNativeConnector.execute("mdnssd", "stop-resolve", resolveId);
495 } catch(NativeDaemonConnectorException e) {
496 Slog.e(TAG, "Failed to stop resolve " + e);
497 return false;
498 }
499 return true;
500 }
501
502 private boolean getAddrInfo(int resolveId, String hostname) {
503 if (DBG) Slog.d(TAG, "getAdddrInfo: " + resolveId);
504 try {
505 mNativeConnector.execute("mdnssd", "getaddrinfo", resolveId, hostname);
506 } catch(NativeDaemonConnectorException e) {
507 Slog.e(TAG, "Failed to getAddrInfo " + e);
508 return false;
509 }
510 return true;
511 }
512
513 private boolean stopGetAddrInfo(int resolveId) {
514 if (DBG) Slog.d(TAG, "stopGetAdddrInfo: " + resolveId);
515 try {
516 mNativeConnector.execute("mdnssd", "stop-getaddrinfo", resolveId);
517 } catch(NativeDaemonConnectorException e) {
518 Slog.e(TAG, "Failed to stopGetAddrInfo " + e);
519 return false;
520 }
521 return true;
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700522 }
523
524 @Override
525 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
526 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
527 != PackageManager.PERMISSION_GRANTED) {
528 pw.println("Permission Denial: can't dump ServiceDiscoverService from from pid="
529 + Binder.getCallingPid()
530 + ", uid=" + Binder.getCallingUid());
531 return;
532 }
533
534 pw.println("Internal state:");
535 }
Irfan Sheriffe8de2462012-04-11 14:52:19 -0700536
537 private ClientInfo getClientByDiscovery(int discoveryId) {
538 for (ClientInfo c: mClients.values()) {
539 if (c.mDiscoveryId == discoveryId) {
540 return c;
541 }
542 }
543 return null;
544 }
545
546 private ClientInfo getClientByResolve(int resolveId) {
547 for (ClientInfo c: mClients.values()) {
548 if (c.mResolveId == resolveId) {
549 return c;
550 }
551 }
552 return null;
553 }
554
555 private ClientInfo getClientByRegistration(int regId) {
556 for (ClientInfo c: mClients.values()) {
557 if (c.mRegisteredIds.contains(regId)) {
558 return c;
559 }
560 }
561 return null;
562 }
563
564 /* Information tracked per client */
565 private class ClientInfo {
566
567 private static final int MAX_REG = 5;
568 private AsyncChannel mChannel;
569 private Messenger mMessenger;
570 private int mDiscoveryId;
571 private int mResolveId;
572 /* Remembers a resolved service until getaddrinfo completes */
573 private DnsSdServiceInfo mResolvedService;
574 private ArrayList<Integer> mRegisteredIds = new ArrayList<Integer>();
575
576 private ClientInfo(AsyncChannel c, Messenger m) {
577 mChannel = c;
578 mMessenger = m;
579 mDiscoveryId = mResolveId = INVALID_ID;
580 if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m);
581 }
582 }
Irfan Sheriff77ec5582012-03-22 17:01:39 -0700583}