17d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff/* 27d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * Copyright (C) 2010 The Android Open Source Project 37d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * 47d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License"); 57d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * you may not use this file except in compliance with the License. 67d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * You may obtain a copy of the License at 77d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * 87d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * http://www.apache.org/licenses/LICENSE-2.0 97d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * 107d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * Unless required by applicable law or agreed to in writing, software 117d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS, 127d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * See the License for the specific language governing permissions and 147d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * limitations under the License. 157d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff */ 167d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 177d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffpackage com.android.server; 187d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 197d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.content.Context; 203ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriffimport android.content.ContentResolver; 213ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriffimport android.content.Intent; 227d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.content.pm.PackageManager; 23919aca5663be997eb238a9635e742858d29b8592Irfan Sheriffimport android.database.ContentObserver; 2422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriffimport android.net.nsd.NsdServiceInfo; 257d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.net.nsd.DnsSdTxtRecord; 267d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.net.nsd.INsdManager; 277d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.net.nsd.NsdManager; 287d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.os.Binder; 297d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.os.Handler; 307d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.os.HandlerThread; 317d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.os.Message; 327d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.os.Messenger; 337d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.os.IBinder; 345ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle; 353ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriffimport android.provider.Settings; 367d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport android.util.Slog; 3722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriffimport android.util.SparseArray; 387d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 397d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport java.io.FileDescriptor; 407d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport java.io.PrintWriter; 41817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriffimport java.net.InetAddress; 427d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport java.util.ArrayList; 43817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriffimport java.util.HashMap; 447d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport java.util.List; 45817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriffimport java.util.concurrent.CountDownLatch; 467d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 477d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport com.android.internal.app.IBatteryStats; 487d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport com.android.internal.telephony.TelephonyIntents; 497d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport com.android.internal.util.AsyncChannel; 503ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriffimport com.android.internal.util.Protocol; 513ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriffimport com.android.internal.util.State; 523ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriffimport com.android.internal.util.StateMachine; 537d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport com.android.server.am.BatteryStatsService; 547d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport com.android.server.NativeDaemonConnector.Command; 557d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffimport com.android.internal.R; 567d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 577d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff/** 587d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * Network Service Discovery Service handles remote service discovery operation requests by 597d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * implementing the INsdManager interface. 607d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * 617d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * @hide 627d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff */ 637d024d372431effc87168afdc7cbe387680c4935Irfan Sheriffpublic class NsdService extends INsdManager.Stub { 647d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff private static final String TAG = "NsdService"; 657d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff private static final String MDNS_TAG = "mDnsConnector"; 667d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 677d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff private static final boolean DBG = true; 687d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 697d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff private Context mContext; 703ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff private ContentResolver mContentResolver; 713ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff private NsdStateMachine mNsdStateMachine; 727d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 737d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff /** 747d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff * Clients receiving asynchronous messages 757d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff */ 76817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>(); 777d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 7822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* A map from unique id to client info */ 7922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<ClientInfo>(); 8022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 817d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff private AsyncChannel mReplyChannel = new AsyncChannel(); 827d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 83817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private int INVALID_ID = 0; 84817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private int mUniqueId = 1; 85817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 863ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff private static final int BASE = Protocol.BASE_NSD_MANAGER; 8722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private static final int CMD_TO_STRING_COUNT = NsdManager.RESOLVE_SERVICE - BASE + 1; 883ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT]; 893ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 903ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff static { 913ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sCmdToString[NsdManager.DISCOVER_SERVICES - BASE] = "DISCOVER"; 923ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sCmdToString[NsdManager.STOP_DISCOVERY - BASE] = "STOP-DISCOVER"; 933ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sCmdToString[NsdManager.REGISTER_SERVICE - BASE] = "REGISTER"; 943ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sCmdToString[NsdManager.UNREGISTER_SERVICE - BASE] = "UNREGISTER"; 953ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sCmdToString[NsdManager.RESOLVE_SERVICE - BASE] = "RESOLVE"; 963ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 977d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 983ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff private static String cmdToString(int cmd) { 993ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff cmd -= BASE; 1003ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if ((cmd >= 0) && (cmd < sCmdToString.length)) { 1013ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return sCmdToString[cmd]; 1023ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 1033ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return null; 1047d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 1053ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 1063ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 1073ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff private class NsdStateMachine extends StateMachine { 1083ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 10922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private final DefaultState mDefaultState = new DefaultState(); 11022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private final DisabledState mDisabledState = new DisabledState(); 11122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private final EnabledState mEnabledState = new EnabledState(); 1127d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 1137d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff @Override 114bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville protected String getWhatToString(int what) { 115bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville return cmdToString(what); 1163ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 1173ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 118919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff /** 119919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff * Observes the NSD on/off setting, and takes action when changed. 120919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff */ 121919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff private void registerForNsdSetting() { 122919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff ContentObserver contentObserver = new ContentObserver(this.getHandler()) { 123919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff @Override 124919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff public void onChange(boolean selfChange) { 125919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff if (isNsdEnabled()) { 126919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff mNsdStateMachine.sendMessage(NsdManager.ENABLE); 127919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff } else { 128919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff mNsdStateMachine.sendMessage(NsdManager.DISABLE); 129919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff } 130919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff } 131919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff }; 132919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff 133919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff mContext.getContentResolver().registerContentObserver( 134625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey Settings.Global.getUriFor(Settings.Global.NSD_ON), 135919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff false, contentObserver); 136919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff } 137919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff 1383ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff NsdStateMachine(String name) { 1393ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff super(name); 1403ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff addState(mDefaultState); 1413ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff addState(mDisabledState, mDefaultState); 1423ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff addState(mEnabledState, mDefaultState); 1433ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (isNsdEnabled()) { 1443ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff setInitialState(mEnabledState); 1453ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 1463ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff setInitialState(mDisabledState); 1473ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 148bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville setLogRecSize(25); 149919aca5663be997eb238a9635e742858d29b8592Irfan Sheriff registerForNsdSetting(); 1503ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 1513ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 1523ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff class DefaultState extends State { 1533ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff @Override 1543ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff public boolean processMessage(Message msg) { 1553ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff switch (msg.what) { 1563ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 1573ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 1583ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff AsyncChannel c = (AsyncChannel) msg.obj; 1593ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (DBG) Slog.d(TAG, "New client listening to asynchronous messages"); 1603ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff c.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED); 1613ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff ClientInfo cInfo = new ClientInfo(c, msg.replyTo); 1623ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mClients.put(msg.replyTo, cInfo); 1633ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 1643ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff Slog.e(TAG, "Client connection failure, error=" + msg.arg1); 165817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 166817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff break; 1673ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 1683ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) { 1693ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff Slog.e(TAG, "Send failed, client connection lost"); 1703ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 1713ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1); 1723ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 1733ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mClients.remove(msg.replyTo); 1743ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 1753ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: 1763ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff AsyncChannel ac = new AsyncChannel(); 1773ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff ac.connect(mContext, getHandler(), msg.replyTo); 1783ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 1793ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.DISCOVER_SERVICES: 18022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED, 18122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 1823ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 1833ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.STOP_DISCOVERY: 18422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED, 18522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 186817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff break; 1873ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.REGISTER_SERVICE: 18822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED, 18922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 1903ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 1913ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.UNREGISTER_SERVICE: 19222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED, 19322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 1943ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 1953ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.RESOLVE_SERVICE: 19622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED, 19722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 1983ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 19922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NsdManager.NATIVE_DAEMON_EVENT: 2003ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff default: 2013ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff Slog.e(TAG, "Unhandled " + msg); 2023ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return NOT_HANDLED; 2033ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2043ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return HANDLED; 2057d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 2067d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 2073ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 2083ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff class DisabledState extends State { 2093ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff @Override 2103ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff public void enter() { 2113ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sendNsdStateChangeBroadcast(false); 2123ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2133ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 2143ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff @Override 2153ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff public boolean processMessage(Message msg) { 2163ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff switch (msg.what) { 2173ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.ENABLE: 2183ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff transitionTo(mEnabledState); 2193ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 2203ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff default: 2213ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return NOT_HANDLED; 2223ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2233ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return HANDLED; 2243ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2253ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2263ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 2273ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff class EnabledState extends State { 2283ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff @Override 2293ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff public void enter() { 2303ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sendNsdStateChangeBroadcast(true); 2313ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (mClients.size() > 0) { 2323ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff startMDnsDaemon(); 2333ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2343ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2353ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 2363ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff @Override 2373ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff public void exit() { 2383ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (mClients.size() > 0) { 2393ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff stopMDnsDaemon(); 2403ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2413ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2423ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 24322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private boolean requestLimitReached(ClientInfo clientInfo) { 24422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (clientInfo.mClientIds.size() >= ClientInfo.MAX_LIMIT) { 24522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "Exceeded max outstanding requests " + clientInfo); 24622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff return true; 24722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 24822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff return false; 24922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 25022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 25122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo) { 25222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mClientIds.put(clientId, globalId); 25322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mIdToClientInfoMap.put(globalId, clientInfo); 25422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 25522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 25622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) { 25722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mClientIds.remove(clientId); 25822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mIdToClientInfoMap.remove(globalId); 25922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 26022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 2613ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff @Override 2623ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff public boolean processMessage(Message msg) { 2633ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff ClientInfo clientInfo; 26422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdServiceInfo servInfo; 2653ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff boolean result = HANDLED; 26622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff int id; 2673ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff switch (msg.what) { 2683ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 2693ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff //First client 2703ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL && 2713ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mClients.size() == 0) { 2723ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff startMDnsDaemon(); 2733ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2743ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff result = NOT_HANDLED; 2753ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 2763ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 2773ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff //Last client 2783ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (mClients.size() == 1) { 2793ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff stopMDnsDaemon(); 2803ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 2813ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff result = NOT_HANDLED; 2823ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 2833ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.DISABLE: 2843ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff //TODO: cleanup clients 2853ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff transitionTo(mDisabledState); 2863ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 2873ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.DISCOVER_SERVICES: 2883ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (DBG) Slog.d(TAG, "Discover services"); 28922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff servInfo = (NsdServiceInfo) msg.obj; 2903ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff clientInfo = mClients.get(msg.replyTo); 29122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 29222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (requestLimitReached(clientInfo)) { 29322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED, 29422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_MAX_LIMIT); 2953ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 2963ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 29722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 29822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff id = getUniqueId(); 29922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (discoverServices(id, servInfo.getServiceType())) { 30022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) { 30122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff Slog.d(TAG, "Discover " + msg.arg2 + " " + id + 30222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff servInfo.getServiceType()); 30322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 30422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff storeRequestMap(msg.arg2, id, clientInfo); 30522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED, servInfo); 3063ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 30722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff stopServiceDiscovery(id); 30822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED, 30922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 3103ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 3113ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 3123ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.STOP_DISCOVERY: 3133ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (DBG) Slog.d(TAG, "Stop service discovery"); 3143ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff clientInfo = mClients.get(msg.replyTo); 31522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 31622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff try { 31722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff id = clientInfo.mClientIds.get(msg.arg2).intValue(); 31822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } catch (NullPointerException e) { 31922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED, 32022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 3213ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 3223ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 32322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff removeRequestMap(msg.arg2, id, clientInfo); 32422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (stopServiceDiscovery(id)) { 32522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED); 3263ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 32722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED, 32822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 3293ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 3303ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 3313ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.REGISTER_SERVICE: 3323ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (DBG) Slog.d(TAG, "Register service"); 3333ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff clientInfo = mClients.get(msg.replyTo); 33422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (requestLimitReached(clientInfo)) { 33522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED, 33622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_MAX_LIMIT); 33722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 3383ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 3393ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 34022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff id = getUniqueId(); 34122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (registerService(id, (NsdServiceInfo) msg.obj)) { 34222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id); 34322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff storeRequestMap(msg.arg2, id, clientInfo); 34422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff // Return success after mDns reports success 3453ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 34622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff unregisterService(id); 34722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED, 34822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 3493ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 3503ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 3513ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.UNREGISTER_SERVICE: 3523ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (DBG) Slog.d(TAG, "unregister service"); 3533ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff clientInfo = mClients.get(msg.replyTo); 35422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff try { 35522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff id = clientInfo.mClientIds.get(msg.arg2).intValue(); 35622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } catch (NullPointerException e) { 35722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED, 35822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 35922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 36022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 36122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff removeRequestMap(msg.arg2, id, clientInfo); 36222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (unregisterService(id)) { 36322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED); 3643ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 36522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED, 36622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 3673ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 3683ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 3693ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff case NsdManager.RESOLVE_SERVICE: 3703ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (DBG) Slog.d(TAG, "Resolve service"); 37122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff servInfo = (NsdServiceInfo) msg.obj; 3723ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff clientInfo = mClients.get(msg.replyTo); 3733ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 37422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 37522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (clientInfo.mResolvedService != null) { 37622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED, 37722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_ALREADY_ACTIVE); 3783ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 3793ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 38022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 38122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff id = getUniqueId(); 38222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (resolveService(id, servInfo)) { 38322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mResolvedService = new NsdServiceInfo(); 38422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff storeRequestMap(msg.arg2, id, clientInfo); 3853ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 38622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED, 38722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR); 3883ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 3893ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 39022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NsdManager.NATIVE_DAEMON_EVENT: 39122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NativeEvent event = (NativeEvent) msg.obj; 39222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff handleNativeEvent(event.code, event.raw, 39322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NativeDaemonEvent.unescapeArgs(event.raw)); 39422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 3953ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff default: 3963ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff result = NOT_HANDLED; 3973ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff break; 3983ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 3993ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return result; 4003ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 4013ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 4027d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 4037d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 4047d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff private NativeDaemonConnector mNativeConnector; 4057d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1); 4067d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 4077d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff private NsdService(Context context) { 4087d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff mContext = context; 4093ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mContentResolver = context.getContentResolver(); 4107d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 4117d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10, 4127d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff MDNS_TAG, 25); 4133ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 4143ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mNsdStateMachine = new NsdStateMachine(TAG); 4153ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mNsdStateMachine.start(); 4163ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 4177d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff Thread th = new Thread(mNativeConnector, MDNS_TAG); 4187d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff th.start(); 4197d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 4207d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 4217d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff public static NsdService create(Context context) throws InterruptedException { 4227d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff NsdService service = new NsdService(context); 4233ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff service.mNativeDaemonConnected.await(); 4247d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff return service; 4257d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 4267d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 4277d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff public Messenger getMessenger() { 42892784670c48759c0db604ddb95c05a7b9bdebed8Irfan Sheriff mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET, 42992784670c48759c0db604ddb95c05a7b9bdebed8Irfan Sheriff "NsdService"); 4303ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return new Messenger(mNsdStateMachine.getHandler()); 4313ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 4323ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 4333ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff public void setEnabled(boolean enable) { 4343ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL, 4353ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff "NsdService"); 436625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey Settings.Global.putInt(mContentResolver, Settings.Global.NSD_ON, enable ? 1 : 0); 4373ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (enable) { 4383ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mNsdStateMachine.sendMessage(NsdManager.ENABLE); 4393ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 4403ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mNsdStateMachine.sendMessage(NsdManager.DISABLE); 4413ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 4423ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 4433ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 4443ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff private void sendNsdStateChangeBroadcast(boolean enabled) { 44554ac7a510245e5f00c16ff5595b6ae8d002c1c3bIrfan Sheriff final Intent intent = new Intent(NsdManager.ACTION_NSD_STATE_CHANGED); 4463ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 4473ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (enabled) { 4483ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff intent.putExtra(NsdManager.EXTRA_NSD_STATE, NsdManager.NSD_STATE_ENABLED); 4493ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } else { 4503ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff intent.putExtra(NsdManager.EXTRA_NSD_STATE, NsdManager.NSD_STATE_DISABLED); 4513ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 4525ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 4533ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 4543ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 4553ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff private boolean isNsdEnabled() { 456625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey boolean ret = Settings.Global.getInt(mContentResolver, Settings.Global.NSD_ON, 1) == 1; 4573ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff if (DBG) Slog.d(TAG, "Network service discovery enabled " + ret); 4583ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return ret; 4597d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 4607d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 461817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private int getUniqueId() { 462817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (++mUniqueId == INVALID_ID) return ++mUniqueId; 463817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return mUniqueId; 464817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 465817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 4667d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff /* These should be in sync with system/netd/mDnsResponseCode.h */ 4677d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff class NativeResponseCode { 468817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_DISCOVERY_FAILED = 602; 469817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_FOUND = 603; 470817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_LOST = 604; 4717d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 472817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_REGISTRATION_FAILED = 605; 473817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_REGISTERED = 606; 4747d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 475817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_RESOLUTION_FAILED = 607; 476817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_RESOLVED = 608; 4777d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 478817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_UPDATED = 609; 479817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_UPDATE_FAILED = 610; 4807d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 481817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_GET_ADDR_FAILED = 611; 482817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff public static final int SERVICE_GET_ADDR_SUCCESS = 612; 483817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 4847d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 48522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private class NativeEvent { 48622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff int code; 48722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff String raw; 48822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 48922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NativeEvent(int code, String raw) { 49022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff this.code = code; 49122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff this.raw = raw; 49222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 49322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 49422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 4957d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks { 4967d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff public void onDaemonConnected() { 4977d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff mNativeDaemonConnected.countDown(); 4987d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 4997d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 5007d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff public boolean onEvent(int code, String raw, String[] cooked) { 50122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff // TODO: NDC translates a message to a callback, we could enhance NDC to 50222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff // directly interact with a state machine through messages 50322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NativeEvent event = new NativeEvent(code, raw); 50422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event); 50522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff return true; 50622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 50722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 508817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 50922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private void handleNativeEvent(int code, String raw, String[] cooked) { 51022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdServiceInfo servInfo; 51122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff int id = Integer.parseInt(cooked[1]); 51222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff ClientInfo clientInfo = mIdToClientInfoMap.get(id); 51322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (clientInfo == null) { 51422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff Slog.e(TAG, "Unique id with no client mapping: " + id); 51522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff return; 51622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 517817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 51822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* This goes in response as msg.arg2 */ 51922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff int clientId = -1; 52022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff int keyId = clientInfo.mClientIds.indexOfValue(id); 52122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (keyId != -1) { 52222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientId = clientInfo.mClientIds.keyAt(keyId); 52322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 52422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff switch (code) { 52522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_FOUND: 52622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN uniqueId serviceName regType domain */ 52722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw); 52822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff servInfo = new NsdServiceInfo(cooked[2], cooked[3], null); 52922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, 0, 53022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientId, servInfo); 53122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 53222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_LOST: 53322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN uniqueId serviceName regType domain */ 53422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw); 53522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff servInfo = new NsdServiceInfo(cooked[2], cooked[3], null); 53622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, 0, 53722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientId, servInfo); 53822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 53922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_DISCOVERY_FAILED: 54022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN uniqueId errorCode */ 54122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw); 54222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED, 54322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR, clientId); 54422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 54522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_REGISTERED: 54622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN regId serviceName regType */ 54722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw); 54822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff servInfo = new NsdServiceInfo(cooked[2], null, null); 54922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED, 55022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff id, clientId, servInfo); 55122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 55222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_REGISTRATION_FAILED: 55322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN regId errorCode */ 55422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw); 55522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED, 55622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR, clientId); 55722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 55822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_UPDATED: 55922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN regId */ 56022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 56122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_UPDATE_FAILED: 56222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN regId errorCode */ 56322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 56422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_RESOLVED: 56522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN resolveId fullName hostName port txtlen txtdata */ 56622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw); 56722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff int index = cooked[2].indexOf("."); 56822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (index == -1) { 56922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff Slog.e(TAG, "Invalid service found " + raw); 5707d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff break; 57122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 57222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff String name = cooked[2].substring(0, index); 57322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff String rest = cooked[2].substring(index); 57422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff String type = rest.replace(".local.", ""); 57522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 57622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mResolvedService.setServiceName(name); 57722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mResolvedService.setServiceType(type); 57822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4])); 579817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 58022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff stopResolveService(id); 58122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (!getAddrInfo(id, cooked[3])) { 582817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED, 58322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR, clientId); 58422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mIdToClientInfoMap.remove(id); 58522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mResolvedService = null; 58622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 58722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 58822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_RESOLUTION_FAILED: 58922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN resolveId errorCode */ 59022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw); 59122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff stopResolveService(id); 59222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mIdToClientInfoMap.remove(id); 59322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mResolvedService = null; 59422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED, 59522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR, clientId); 59622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 59722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_GET_ADDR_FAILED: 59822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN resolveId errorCode */ 59922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff stopGetAddrInfo(id); 60022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mIdToClientInfoMap.remove(id); 60122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mResolvedService = null; 60222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw); 60322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED, 60422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR, clientId); 60522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 60622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS: 60722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* NNN resolveId hostname ttl addr */ 60822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw); 60922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff try { 61022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4])); 61122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED, 61222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 0, clientId, clientInfo.mResolvedService); 61322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } catch (java.net.UnknownHostException e) { 61422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED, 61522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff NsdManager.FAILURE_INTERNAL_ERROR, clientId); 61622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 61722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff stopGetAddrInfo(id); 61822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mIdToClientInfoMap.remove(id); 61922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff clientInfo.mResolvedService = null; 62022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 62122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff default: 62222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff break; 6237d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 6247d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 6257d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 626817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private boolean startMDnsDaemon() { 627817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "startMDnsDaemon"); 628817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff try { 629817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mNativeConnector.execute("mdnssd", "start-service"); 630817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } catch(NativeDaemonConnectorException e) { 631817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to start daemon" + e); 632817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 633817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 634817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 635817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 636817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 637817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private boolean stopMDnsDaemon() { 638817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "stopMDnsDaemon"); 639817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff try { 640817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mNativeConnector.execute("mdnssd", "stop-service"); 641817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } catch(NativeDaemonConnectorException e) { 642817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to start daemon" + e); 643817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 644817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 645817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 646817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 647817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 64822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private boolean registerService(int regId, NsdServiceInfo service) { 649817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service); 6507d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff try { 6517d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff //Add txtlen and txtdata 6527d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff mNativeConnector.execute("mdnssd", "register", regId, service.getServiceName(), 6537d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff service.getServiceType(), service.getPort()); 6547d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } catch(NativeDaemonConnectorException e) { 655817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to execute registerService " + e); 656817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 657817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 658817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 659817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 660817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 661817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private boolean unregisterService(int regId) { 662817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "unregisterService: " + regId); 663817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff try { 664817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mNativeConnector.execute("mdnssd", "stop-register", regId); 665817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } catch(NativeDaemonConnectorException e) { 666817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to execute unregisterService " + e); 667817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 6687d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 669817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 6707d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 6717d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 672817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private boolean updateService(int regId, DnsSdTxtRecord t) { 673817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "updateService: " + regId + " " + t); 6747d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff try { 675817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (t == null) return false; 6767d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff mNativeConnector.execute("mdnssd", "update", regId, t.size(), t.getRawData()); 6777d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } catch(NativeDaemonConnectorException e) { 678817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to updateServices " + e); 679817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 6807d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 681817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 6827d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 6837d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 684817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private boolean discoverServices(int discoveryId, String serviceType) { 685817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "discoverServices: " + discoveryId + " " + serviceType); 6867d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff try { 6877d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff mNativeConnector.execute("mdnssd", "discover", discoveryId, serviceType); 6887d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } catch(NativeDaemonConnectorException e) { 689817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to discoverServices " + e); 690817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 691817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 692817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 693817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 694817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 695817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private boolean stopServiceDiscovery(int discoveryId) { 696817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "stopServiceDiscovery: " + discoveryId); 697817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff try { 698817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mNativeConnector.execute("mdnssd", "stop-discover", discoveryId); 699817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } catch(NativeDaemonConnectorException e) { 700817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to stopServiceDiscovery " + e); 701817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 702817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 703817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 704817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 705817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 70622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private boolean resolveService(int resolveId, NsdServiceInfo service) { 707817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service); 708817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff try { 709817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(), 710817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff service.getServiceType(), "local."); 711817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } catch(NativeDaemonConnectorException e) { 712817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to resolveService " + e); 713817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 714817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 715817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 716817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 717817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 718817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private boolean stopResolveService(int resolveId) { 719817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "stopResolveService: " + resolveId); 720817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff try { 721817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mNativeConnector.execute("mdnssd", "stop-resolve", resolveId); 722817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } catch(NativeDaemonConnectorException e) { 723817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to stop resolve " + e); 724817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 7257d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 726817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 7277d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 7287d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 729817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private boolean getAddrInfo(int resolveId, String hostname) { 730817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "getAdddrInfo: " + resolveId); 7317d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff try { 732817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mNativeConnector.execute("mdnssd", "getaddrinfo", resolveId, hostname); 7337d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } catch(NativeDaemonConnectorException e) { 734817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to getAddrInfo " + e); 735817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 7367d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 737817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 7387d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 7397d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 740817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private boolean stopGetAddrInfo(int resolveId) { 741817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "stopGetAdddrInfo: " + resolveId); 7427d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff try { 743817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mNativeConnector.execute("mdnssd", "stop-getaddrinfo", resolveId); 7447d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } catch(NativeDaemonConnectorException e) { 745817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff Slog.e(TAG, "Failed to stopGetAddrInfo " + e); 746817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return false; 7477d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 748817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff return true; 7497d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 7507d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 7517d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff @Override 7523ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 7537d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 7547d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff != PackageManager.PERMISSION_GRANTED) { 7557d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff pw.println("Permission Denial: can't dump ServiceDiscoverService from from pid=" 7567d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff + Binder.getCallingPid() 7577d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff + ", uid=" + Binder.getCallingUid()); 7587d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff return; 7597d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 7607d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff 7613ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff for (ClientInfo client : mClients.values()) { 7623ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff pw.println("Client Info"); 7633ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff pw.println(client); 7643ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 7653ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 7663ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff mNsdStateMachine.dump(fd, pw, args); 7677d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff } 768817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 76922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* arg2 on the source message has an id that needs to be retained in replies 77022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff * see NsdManager for details */ 77122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private Message obtainMessage(Message srcMsg) { 77222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff Message msg = Message.obtain(); 77322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff msg.arg2 = srcMsg.arg2; 77422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff return msg; 775817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 776817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 77722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private void replyToMessage(Message msg, int what) { 77822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (msg.replyTo == null) return; 77922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff Message dstMsg = obtainMessage(msg); 78022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff dstMsg.what = what; 78122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mReplyChannel.replyToMessage(msg, dstMsg); 782817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 783817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 78422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private void replyToMessage(Message msg, int what, int arg1) { 78522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (msg.replyTo == null) return; 78622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff Message dstMsg = obtainMessage(msg); 78722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff dstMsg.what = what; 78822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff dstMsg.arg1 = arg1; 78922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mReplyChannel.replyToMessage(msg, dstMsg); 79022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff } 79122af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 79222af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private void replyToMessage(Message msg, int what, Object obj) { 79322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff if (msg.replyTo == null) return; 79422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff Message dstMsg = obtainMessage(msg); 79522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff dstMsg.what = what; 79622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff dstMsg.obj = obj; 79722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff mReplyChannel.replyToMessage(msg, dstMsg); 798817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 799817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 800817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff /* Information tracked per client */ 801817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private class ClientInfo { 802817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 80322af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private static final int MAX_LIMIT = 10; 804817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private AsyncChannel mChannel; 805817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private Messenger mMessenger; 806817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff /* Remembers a resolved service until getaddrinfo completes */ 80722af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private NsdServiceInfo mResolvedService; 80822af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff 80922af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff /* A map from client id to unique id sent to mDns */ 81022af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff private SparseArray<Integer> mClientIds = new SparseArray<Integer>(); 811817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff 812817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff private ClientInfo(AsyncChannel c, Messenger m) { 813817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mChannel = c; 814817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff mMessenger = m; 815817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m); 816817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 8173ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff 8183ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff @Override 8193ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff public String toString() { 8203ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff StringBuffer sb = new StringBuffer(); 8213ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sb.append("mChannel ").append(mChannel).append("\n"); 8223ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sb.append("mMessenger ").append(mMessenger).append("\n"); 8233ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff sb.append("mResolvedService ").append(mResolvedService).append("\n"); 82422af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff for(int i = 0; i< mClientIds.size(); i++) { 82522af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff sb.append("clientId ").append(mClientIds.keyAt(i)); 82622af38c5261d2c03796b496e6edb125327cace16Irfan Sheriff sb.append(" mDnsId ").append(mClientIds.valueAt(i)).append("\n"); 8273ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 8283ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff return sb.toString(); 8293ef889bf561e59561ff2c6c4b2ffb586b9c5af5cIrfan Sheriff } 830817388e056a5d1d0e7cd7de2c6b0c9c80617bc5fIrfan Sheriff } 8317d024d372431effc87168afdc7cbe387680c4935Irfan Sheriff} 832