1b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo/*
2b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo * Copyright (C) 2016 The Android Open Source Project
3b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo *
4b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo * Licensed under the Apache License, Version 2.0 (the "License");
5b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo * you may not use this file except in compliance with the License.
6b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo * You may obtain a copy of the License at
7b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo *
8b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo *      http://www.apache.org/licenses/LICENSE-2.0
9b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo *
10b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo * Unless required by applicable law or agreed to in writing, software
11b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo * distributed under the License is distributed on an "AS IS" BASIS,
12b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo * See the License for the specific language governing permissions and
14b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo * limitations under the License.
15b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo */
16b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
17b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzopackage com.android.bluetooth.pbapclient;
18b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
19b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport android.os.Handler;
20b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport android.os.HandlerThread;
21b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport android.os.Looper;
22b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport android.os.Message;
23b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport android.util.Log;
24b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
25b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport java.io.IOException;
26b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport java.lang.ref.WeakReference;
27b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
28b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport javax.obex.ClientSession;
29b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport javax.obex.HeaderSet;
30b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport javax.obex.ObexTransport;
31b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzoimport javax.obex.ResponseCodes;
32b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
33b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzofinal class BluetoothPbapObexSession {
34b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private static final boolean DBG = true;
35b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private static final String TAG = "BluetoothPbapObexSession";
36b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
37b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private static final byte[] PBAP_TARGET = new byte[] {
38b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            0x79, 0x61, 0x35, (byte) 0xf0, (byte) 0xf0, (byte) 0xc5, 0x11, (byte) 0xd8, 0x09, 0x66,
39b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            0x08, 0x00, 0x20, 0x0c, (byte) 0x9a, 0x66
40b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    };
41b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
42b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int OBEX_SESSION_CONNECTED = 100;
43b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int OBEX_SESSION_FAILED = 101;
44b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int OBEX_SESSION_DISCONNECTED = 102;
45b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int OBEX_SESSION_REQUEST_COMPLETED = 103;
46b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int OBEX_SESSION_REQUEST_FAILED = 104;
47b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int OBEX_SESSION_AUTHENTICATION_REQUEST = 105;
48b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int OBEX_SESSION_AUTHENTICATION_TIMEOUT = 106;
49b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
50b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int MSG_CONNECT = 0;
51b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int MSG_REQUEST = 1;
52b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
53b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int CONNECTED = 0;
54b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int CONNECTING = 1;
55b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    final static int DISCONNECTED = 2;
56b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
57b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private Handler mSessionHandler;
58b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private final ObexTransport mTransport;
59b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    // private ObexClientThread mObexClientThread;
60b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private BluetoothPbapObexAuthenticator mAuth = null;
61b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private HandlerThread mThread;
62b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private Handler mHandler;
63b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private ClientSession mClientSession;
64b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
65b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private int mState = DISCONNECTED;
66b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
67b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    public BluetoothPbapObexSession(ObexTransport transport) {
68b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mTransport = transport;
69b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
70b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
71b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    public synchronized boolean start(Handler handler) {
72b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        Log.d(TAG, "start");
73b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
74b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (mState == CONNECTED || mState == CONNECTING) {
75b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            return false;
76b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
77b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mState = CONNECTING;
78b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mSessionHandler = handler;
79b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
80b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mAuth = new BluetoothPbapObexAuthenticator(mSessionHandler);
81b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
82b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        // Start the thread to process requests (see {@link schedule()}.
83b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mThread = new HandlerThread("BluetoothPbapObexSessionThread");
84b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mThread.start();
85b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mHandler = new ObexClientHandler(mThread.getLooper(), this);
86b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
87b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        // Make connect call non blocking.
88b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        boolean status = mHandler.sendMessage(mHandler.obtainMessage(MSG_CONNECT));
89b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (!status) {
90b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            mState = DISCONNECTED;
91b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            return false;
92b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        } else {
93b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            return true;
94b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
95b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
96b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
97b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    public void stop() {
98b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (DBG) {
99b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            Log.d(TAG, "stop");
100b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
101b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
102b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        // This will essentially stop the handler and ignore any inflight requests.
103b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mThread.quit();
104b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
105b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        // We clean up the state here.
106b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        disconnect(false /* no callback */);
107b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
108b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
109b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    public void abort() {
110b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        stop();
111b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
112b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
113b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    public boolean schedule(BluetoothPbapRequest request) {
114b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (DBG) {
115b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            Log.d(TAG, "schedule() called with: " + request);
116b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
117b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
118b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        boolean status = mHandler.sendMessage(mHandler.obtainMessage(MSG_REQUEST, request));
119b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (!status) {
120b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            Log.e(TAG, "Adding messages failed, obex must be disconnected.");
121b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            return false;
122b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
123b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        return true;
124b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
125b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
126b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    public int isConnected() {
127b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        return mState;
128b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
129b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
130b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private void connect() {
131b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       if (DBG) {
132b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo          Log.d(TAG, "connect()");
133b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       }
134b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
135b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       boolean success = true;
136b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       try {
137b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo          mClientSession = new ClientSession(mTransport);
138b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo          mClientSession.setAuthenticator(mAuth);
139b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       } catch (IOException e) {
140b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo          Log.d(TAG, "connect() exception: " + e);
141b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo          success = false;
142b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       }
143b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
144b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       HeaderSet hs = new HeaderSet();
145b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       hs.setHeader(HeaderSet.TARGET, PBAP_TARGET);
146b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       try {
147b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo          hs = mClientSession.connect(hs);
148b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
149b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo          if (hs.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
150b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo              disconnect(true  /* callback */);
151b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo              success = false;
152b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo          }
153b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       } catch (IOException e) {
154b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo          success = false;
155b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       }
156b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
157b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       synchronized (this) {
158b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo           if (success) {
159b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo              mSessionHandler.obtainMessage(OBEX_SESSION_CONNECTED).sendToTarget();
160b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo              mState = CONNECTED;
161b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo           } else {
162b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo              mSessionHandler.obtainMessage(OBEX_SESSION_DISCONNECTED).sendToTarget();
163b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo              mState = DISCONNECTED;
164b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo           }
165b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo       }
166b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
167b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
168b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private synchronized void disconnect(boolean callback) {
169b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (DBG) {
170b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            Log.d(TAG, "disconnect()");
171b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
172b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
173b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (mState != DISCONNECTED) {
174b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            return;
175b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
176b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
177b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (mClientSession != null) {
178b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            try {
179b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                mClientSession.disconnect(null);
180b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                mClientSession.close();
181b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            } catch (IOException e) {
182b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            }
183b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
184b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
185b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (callback) {
186b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            mSessionHandler.obtainMessage(OBEX_SESSION_DISCONNECTED).sendToTarget();
187b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
188b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
189b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mState = DISCONNECTED;
190b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
191b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
192b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private void executeRequest(BluetoothPbapRequest req) {
193b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        try {
194b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            req.execute(mClientSession);
195b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        } catch (IOException e) {
196b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            Log.e(TAG, "Error during executeRequest " + e);
197b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            disconnect(true);
198b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
199b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
200b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (req.isSuccess()) {
201b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            mSessionHandler.obtainMessage(OBEX_SESSION_REQUEST_COMPLETED, req).sendToTarget();
202b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        } else {
203b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            mSessionHandler.obtainMessage(OBEX_SESSION_REQUEST_FAILED, req).sendToTarget();
204b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
205b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
206b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
207b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    public boolean setAuthReply(String key) {
208b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        Log.d(TAG, "setAuthReply key=" + key);
209b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
210b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        if (mAuth == null) {
211b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            return false;
212b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
213b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
214b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        mAuth.setReply(key);
215b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
216b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        return true;
217b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
218b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
219b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    private static class ObexClientHandler extends Handler {
220b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        WeakReference<BluetoothPbapObexSession> mInst;
221b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
222b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        ObexClientHandler(Looper looper, BluetoothPbapObexSession inst) {
223b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            super(looper);
224b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            mInst = new WeakReference<BluetoothPbapObexSession>(inst);
225b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
226b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
227b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        @Override
228b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        public void handleMessage(Message msg) {
229b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            BluetoothPbapObexSession inst = mInst.get();
230b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            if (inst == null) {
231b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                Log.e(TAG, "The instance class is no longer around; terminating.");
232b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                return;
233b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            }
234b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
235b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            if (inst.isConnected() != CONNECTED && msg.what != MSG_CONNECT) {
236b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                Log.w(TAG, "Cannot execute " + msg + " when not CONNECTED.");
237b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                return;
238b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            }
239b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
240b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            switch (msg.what) {
241b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                case MSG_CONNECT:
242b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                    inst.connect();
243b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                    break;
244b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                case MSG_REQUEST:
245b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                    inst.executeRequest((BluetoothPbapRequest) msg.obj);
246b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                    break;
247b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                default:
248b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo                    Log.e(TAG, "Unknwown message type: " + msg.what);
249b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo            }
250b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo        }
251b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo    }
252b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo}
253b874a1d1cf25f90947ba87f791d42a404cad7d85Joseph Pirozzo
254