diff options
author | Joseph Pirozzo <pirozzoj@google.com> | 2016-04-11 17:50:08 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-04-11 17:50:08 +0000 |
commit | f78ef68c69736a4210137e8487dc137e90d026fb (patch) | |
tree | f25858994ce26e93c10a953d7ea8900dfa357d11 | |
parent | 818fbc8b8221dda64f81bc9e833fc479cab4b2f1 (diff) | |
parent | acddae0220818a2079246533605cb468cf159963 (diff) | |
download | bluetooth-f78ef68c69736a4210137e8487dc137e90d026fb.tar.gz |
PBAP migration to BT Profile am: ced8b4e
am: acddae0
* commit 'acddae0220818a2079246533605cb468cf159963':
PBAP migration to BT Profile
Change-Id: I74ddbcc69c3cad77257c3f92550bbfbc0d990fa1
18 files changed, 0 insertions, 2964 deletions
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapCard.java b/src/android/bluetooth/client/pbap/BluetoothPbapCard.java deleted file mode 100644 index 6c4fadc..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapCard.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import com.android.vcard.VCardEntry; -import com.android.vcard.VCardEntry.EmailData; -import com.android.vcard.VCardEntry.NameData; -import com.android.vcard.VCardEntry.PhoneData; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.List; - -/** - * Entry representation of folder listing - */ -public class BluetoothPbapCard { - - public final String handle; - - public final String N; - public final String lastName; - public final String firstName; - public final String middleName; - public final String prefix; - public final String suffix; - - public BluetoothPbapCard(String handle, String name) { - this.handle = handle; - - N = name; - - /* - * format is as for vCard N field, so we have up to 5 tokens: LastName; - * FirstName; MiddleName; Prefix; Suffix - */ - String[] parsedName = name.split(";", 5); - - lastName = parsedName.length < 1 ? null : parsedName[0]; - firstName = parsedName.length < 2 ? null : parsedName[1]; - middleName = parsedName.length < 3 ? null : parsedName[2]; - prefix = parsedName.length < 4 ? null : parsedName[3]; - suffix = parsedName.length < 5 ? null : parsedName[4]; - } - - @Override - public String toString() { - JSONObject json = new JSONObject(); - - try { - json.put("handle", handle); - json.put("N", N); - json.put("lastName", lastName); - json.put("firstName", firstName); - json.put("middleName", middleName); - json.put("prefix", prefix); - json.put("suffix", suffix); - } catch (JSONException e) { - // do nothing - } - - return json.toString(); - } - - static public String jsonifyVcardEntry(VCardEntry vcard) { - JSONObject json = new JSONObject(); - - try { - NameData name = vcard.getNameData(); - json.put("formatted", name.getFormatted()); - json.put("family", name.getFamily()); - json.put("given", name.getGiven()); - json.put("middle", name.getMiddle()); - json.put("prefix", name.getPrefix()); - json.put("suffix", name.getSuffix()); - } catch (JSONException e) { - // do nothing - } - - try { - JSONArray jsonPhones = new JSONArray(); - - List<PhoneData> phones = vcard.getPhoneList(); - - if (phones != null) { - for (PhoneData phone : phones) { - JSONObject jsonPhone = new JSONObject(); - jsonPhone.put("type", phone.getType()); - jsonPhone.put("number", phone.getNumber()); - jsonPhone.put("label", phone.getLabel()); - jsonPhone.put("is_primary", phone.isPrimary()); - - jsonPhones.put(jsonPhone); - } - - json.put("phones", jsonPhones); - } - } catch (JSONException e) { - // do nothing - } - - try { - JSONArray jsonEmails = new JSONArray(); - - List<EmailData> emails = vcard.getEmailList(); - - if (emails != null) { - for (EmailData email : emails) { - JSONObject jsonEmail = new JSONObject(); - jsonEmail.put("type", email.getType()); - jsonEmail.put("address", email.getAddress()); - jsonEmail.put("label", email.getLabel()); - jsonEmail.put("is_primary", email.isPrimary()); - - jsonEmails.put(jsonEmail); - } - - json.put("emails", jsonEmails); - } - } catch (JSONException e) { - // do nothing - } - - return json.toString(); - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapClient.java b/src/android/bluetooth/client/pbap/BluetoothPbapClient.java deleted file mode 100644 index b1fc441..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapClient.java +++ /dev/null @@ -1,857 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.accounts.Account; -import android.bluetooth.BluetoothDevice; -import android.os.Handler; -import android.os.Message; -import android.util.Log; - -import java.lang.ref.WeakReference; - -/** - * Public API to control Phone Book Profile (PCE role only). - * <p> - * This class defines methods that shall be used by application for the - * retrieval of phone book objects from remote device. - * <p> - * How to connect to remote device which is acting in PSE role: - * <ul> - * <li>Create a <code>BluetoothDevice</code> object which corresponds to remote - * device in PSE role; - * <li>Create an instance of <code>BluetoothPbapClient</code> class, passing - * <code>BluetothDevice</code> object along with a <code>Handler</code> to it; - * <li>Use {@link #setPhoneBookFolderRoot}, {@link #setPhoneBookFolderUp} and - * {@link #setPhoneBookFolderDown} to navigate in virtual phone book folder - * structure - * <li>Use {@link #pullPhoneBookSize} or {@link #pullVcardListingSize} to - * retrieve the size of selected phone book - * <li>Use {@link #pullPhoneBook} to retrieve phone book entries - * <li>Use {@link #pullVcardListing} to retrieve list of entries in the phone - * book - * <li>Use {@link #pullVcardEntry} to pull single entry from the phone book - * </ul> - * Upon completion of each call above PCE will notify application if operation - * completed successfully (along with results) or failed. - * <p> - * Therefore, application should handle following events in its message queue - * handler: - * <ul> - * <li><code>EVENT_PULL_PHONE_BOOK_SIZE_DONE</code> - * <li><code>EVENT_PULL_VCARD_LISTING_SIZE_DONE</code> - * <li><code>EVENT_PULL_PHONE_BOOK_DONE</code> - * <li><code>EVENT_PULL_VCARD_LISTING_DONE</code> - * <li><code>EVENT_PULL_VCARD_ENTRY_DONE</code> - * <li><code>EVENT_SET_PHONE_BOOK_DONE</code> - * </ul> - * and - * <ul> - * <li><code>EVENT_PULL_PHONE_BOOK_SIZE_ERROR</code> - * <li><code>EVENT_PULL_VCARD_LISTING_SIZE_ERROR</code> - * <li><code>EVENT_PULL_PHONE_BOOK_ERROR</code> - * <li><code>EVENT_PULL_VCARD_LISTING_ERROR</code> - * <li><code>EVENT_PULL_VCARD_ENTRY_ERROR</code> - * <li><code>EVENT_SET_PHONE_BOOK_ERROR</code> - * </ul> - * <code>connect</code> and <code>disconnect</code> methods are introduced for - * testing purposes. An application does not need to use them as the session - * connection and disconnection happens automatically internally. - */ -public class BluetoothPbapClient { - private static final boolean DBG = true; - - private static final String TAG = "BluetoothPbapClient"; - - /** - * Path to local incoming calls history object - */ - public static final String ICH_PATH = "telecom/ich.vcf"; - - /** - * Path to local outgoing calls history object - */ - public static final String OCH_PATH = "telecom/och.vcf"; - - /** - * Path to local missed calls history object - */ - public static final String MCH_PATH = "telecom/mch.vcf"; - - /** - * Path to local combined calls history object - */ - public static final String CCH_PATH = "telecom/cch.vcf"; - - /** - * Path to local main phone book object - */ - public static final String PB_PATH = "telecom/pb.vcf"; - - /** - * Path to incoming calls history object stored on the phone's SIM card - */ - public static final String SIM_ICH_PATH = "SIM1/telecom/ich.vcf"; - - /** - * Path to outgoing calls history object stored on the phone's SIM card - */ - public static final String SIM_OCH_PATH = "SIM1/telecom/och.vcf"; - - /** - * Path to missed calls history object stored on the phone's SIM card - */ - public static final String SIM_MCH_PATH = "SIM1/telecom/mch.vcf"; - - /** - * Path to combined calls history object stored on the phone's SIM card - */ - public static final String SIM_CCH_PATH = "SIM1/telecom/cch.vcf"; - - /** - * Path to main phone book object stored on the phone's SIM card - */ - public static final String SIM_PB_PATH = "SIM1/telecom/pb.vcf"; - - /** - * Indicates to server that default sorting order shall be used for vCard - * listing. - */ - public static final byte ORDER_BY_DEFAULT = -1; - - /** - * Indicates to server that indexed sorting order shall be used for vCard - * listing. - */ - public static final byte ORDER_BY_INDEXED = 0; - - /** - * Indicates to server that alphabetical sorting order shall be used for the - * vCard listing. - */ - public static final byte ORDER_BY_ALPHABETICAL = 1; - - /** - * Indicates to server that phonetical (based on sound attribute) sorting - * order shall be used for the vCard listing. - */ - public static final byte ORDER_BY_PHONETIC = 2; - - /** - * Indicates to server that Name attribute of vCard shall be used to carry - * out the search operation on - */ - public static final byte SEARCH_ATTR_NAME = 0; - - /** - * Indicates to server that Number attribute of vCard shall be used to carry - * out the search operation on - */ - public static final byte SEARCH_ATTR_NUMBER = 1; - - /** - * Indicates to server that Sound attribute of vCard shall be used to carry - * out the search operation - */ - public static final byte SEARCH_ATTR_SOUND = 2; - - /** - * VCard format version 2.1 - */ - public static final byte VCARD_TYPE_21 = 0; - - /** - * VCard format version 3.0 - */ - public static final byte VCARD_TYPE_30 = 1; - - /* 64-bit mask used to filter out VCard fields */ - // TODO: Think of extracting to separate class - public static final long VCARD_ATTR_VERSION = 0x000000000000000001; - public static final long VCARD_ATTR_FN = 0x000000000000000002; - public static final long VCARD_ATTR_N = 0x000000000000000004; - public static final long VCARD_ATTR_PHOTO = 0x000000000000000008; - public static final long VCARD_ATTR_BDAY = 0x000000000000000010; - public static final long VCARD_ATTR_ADDR = 0x000000000000000020; - public static final long VCARD_ATTR_LABEL = 0x000000000000000040; - public static final long VCARD_ATTR_TEL = 0x000000000000000080; - public static final long VCARD_ATTR_EMAIL = 0x000000000000000100; - public static final long VCARD_ATTR_MAILER = 0x000000000000000200; - public static final long VCARD_ATTR_TZ = 0x000000000000000400; - public static final long VCARD_ATTR_GEO = 0x000000000000000800; - public static final long VCARD_ATTR_TITLE = 0x000000000000001000; - public static final long VCARD_ATTR_ROLE = 0x000000000000002000; - public static final long VCARD_ATTR_LOGO = 0x000000000000004000; - public static final long VCARD_ATTR_AGENT = 0x000000000000008000; - public static final long VCARD_ATTR_ORG = 0x000000000000010000; - public static final long VCARD_ATTR_NOTE = 0x000000000000020000; - public static final long VCARD_ATTR_REV = 0x000000000000040000; - public static final long VCARD_ATTR_SOUND = 0x000000000000080000; - public static final long VCARD_ATTR_URL = 0x000000000000100000; - public static final long VCARD_ATTR_UID = 0x000000000000200000; - public static final long VCARD_ATTR_KEY = 0x000000000000400000; - public static final long VCARD_ATTR_NICKNAME = 0x000000000000800000; - public static final long VCARD_ATTR_CATEGORIES = 0x000000000001000000; - public static final long VCARD_ATTR_PROID = 0x000000000002000000; - public static final long VCARD_ATTR_CLASS = 0x000000000004000000; - public static final long VCARD_ATTR_SORT_STRING = 0x000000000008000000; - public static final long VCARD_ATTR_X_IRMC_CALL_DATETIME = - 0x000000000010000000; - - /** - * Maximal number of entries of the phone book that PCE can handle - */ - public static final short MAX_LIST_COUNT = (short) 0xFFFF; - - /** - * Event propagated upon completion of <code>setPhoneBookFolderRoot</code>, - * <code>setPhoneBookFolderUp</code> or <code>setPhoneBookFolderDown</code> - * request. - * <p> - * This event indicates that request completed successfully. - * @see #setPhoneBookFolderRoot - * @see #setPhoneBookFolderUp - * @see #setPhoneBookFolderDown - */ - public static final int EVENT_SET_PHONE_BOOK_DONE = 1; - - /** - * Event propagated upon completion of <code>pullPhoneBook</code> request. - * <p> - * This event carry on results of the request. - * <p> - * The resulting message contains: - * <table> - * <tr> - * <td><code>msg.arg1</code></td> - * <td>newMissedCalls parameter (only in case of missed calls history object - * request)</td> - * </tr> - * <tr> - * <td><code>msg.obj</code></td> - * <td>which is a list of <code>VCardEntry</code> objects</td> - * </tr> - * </table> - * @see #pullPhoneBook - */ - public static final int EVENT_PULL_PHONE_BOOK_DONE = 2; - - /** - * Event propagated upon completion of <code>pullVcardListing</code> - * request. - * <p> - * This event carry on results of the request. - * <p> - * The resulting message contains: - * <table> - * <tr> - * <td><code>msg.arg1</code></td> - * <td>newMissedCalls parameter (only in case of missed calls history object - * request)</td> - * </tr> - * <tr> - * <td><code>msg.obj</code></td> - * <td>which is a list of <code>BluetoothPbapCard</code> objects</td> - * </tr> - * </table> - * @see #pullVcardListing - */ - public static final int EVENT_PULL_VCARD_LISTING_DONE = 3; - - /** - * Event propagated upon completion of <code>pullVcardEntry</code> request. - * <p> - * This event carry on results of the request. - * <p> - * The resulting message contains: - * <table> - * <tr> - * <td><code>msg.obj</code></td> - * <td>vCard as and object of type <code>VCardEntry</code></td> - * </tr> - * </table> - * @see #pullVcardEntry - */ - public static final int EVENT_PULL_VCARD_ENTRY_DONE = 4; - - /** - * Event propagated upon completion of <code>pullPhoneBookSize</code> - * request. - * <p> - * This event carry on results of the request. - * <p> - * The resulting message contains: - * <table> - * <tr> - * <td><code>msg.arg1</code></td> - * <td>size of the phone book</td> - * </tr> - * </table> - * @see #pullPhoneBookSize - */ - public static final int EVENT_PULL_PHONE_BOOK_SIZE_DONE = 5; - - /** - * Event propagated upon completion of <code>pullVcardListingSize</code> - * request. - * <p> - * This event carry on results of the request. - * <p> - * The resulting message contains: - * <table> - * <tr> - * <td><code>msg.arg1</code></td> - * <td>size of the phone book listing</td> - * </tr> - * </table> - * @see #pullVcardListingSize - */ - public static final int EVENT_PULL_VCARD_LISTING_SIZE_DONE = 6; - - /** - * Event propagated upon completion of <code>setPhoneBookFolderRoot</code>, - * <code>setPhoneBookFolderUp</code> or <code>setPhoneBookFolderDown</code> - * request. This event indicates an error during operation. - */ - public static final int EVENT_SET_PHONE_BOOK_ERROR = 101; - - /** - * Event propagated upon completion of <code>pullPhoneBook</code> request. - * This event indicates an error during operation. - */ - public static final int EVENT_PULL_PHONE_BOOK_ERROR = 102; - - /** - * Event propagated upon completion of <code>pullVcardListing</code> - * request. This event indicates an error during operation. - */ - public static final int EVENT_PULL_VCARD_LISTING_ERROR = 103; - - /** - * Event propagated upon completion of <code>pullVcardEntry</code> request. - * This event indicates an error during operation. - */ - public static final int EVENT_PULL_VCARD_ENTRY_ERROR = 104; - - /** - * Event propagated upon completion of <code>pullPhoneBookSize</code> - * request. This event indicates an error during operation. - */ - public static final int EVENT_PULL_PHONE_BOOK_SIZE_ERROR = 105; - - /** - * Event propagated upon completion of <code>pullVcardListingSize</code> - * request. This event indicates an error during operation. - */ - public static final int EVENT_PULL_VCARD_LISTING_SIZE_ERROR = 106; - - /** - * Event propagated when PCE has been connected to PSE - */ - public static final int EVENT_SESSION_CONNECTED = 201; - - /** - * Event propagated when PCE has been disconnected from PSE - */ - public static final int EVENT_SESSION_DISCONNECTED = 202; - public static final int EVENT_SESSION_AUTH_REQUESTED = 203; - public static final int EVENT_SESSION_AUTH_TIMEOUT = 204; - - public enum ConnectionState { - DISCONNECTED, CONNECTING, CONNECTED, DISCONNECTING; - } - - private final Account mAccount; - private final Handler mClientHandler; - private final BluetoothPbapSession mSession; - private ConnectionState mConnectionState = ConnectionState.DISCONNECTED; - - private SessionHandler mSessionHandler; - - private static class SessionHandler extends Handler { - - private final WeakReference<BluetoothPbapClient> mClient; - - SessionHandler(BluetoothPbapClient client) { - mClient = new WeakReference<BluetoothPbapClient>(client); - } - - @Override - public void handleMessage(Message msg) { - Log.d(TAG, "handleMessage: what=" + msg.what); - - BluetoothPbapClient client = mClient.get(); - if (client == null) { - return; - } - - switch (msg.what) { - case BluetoothPbapSession.REQUEST_FAILED: - { - BluetoothPbapRequest req = (BluetoothPbapRequest) msg.obj; - - if (req instanceof BluetoothPbapRequestPullPhoneBookSize) { - client.sendToClient(EVENT_PULL_PHONE_BOOK_SIZE_ERROR); - } else if (req instanceof BluetoothPbapRequestPullVcardListingSize) { - client.sendToClient(EVENT_PULL_VCARD_LISTING_SIZE_ERROR); - } else if (req instanceof BluetoothPbapRequestPullPhoneBook) { - client.sendToClient(EVENT_PULL_PHONE_BOOK_ERROR); - } else if (req instanceof BluetoothPbapRequestPullVcardListing) { - client.sendToClient(EVENT_PULL_VCARD_LISTING_ERROR); - } else if (req instanceof BluetoothPbapRequestPullVcardEntry) { - client.sendToClient(EVENT_PULL_VCARD_ENTRY_ERROR); - } else if (req instanceof BluetoothPbapRequestSetPath) { - client.sendToClient(EVENT_SET_PHONE_BOOK_ERROR); - } - - break; - } - - case BluetoothPbapSession.REQUEST_COMPLETED: - { - BluetoothPbapRequest req = (BluetoothPbapRequest) msg.obj; - - if (req instanceof BluetoothPbapRequestPullPhoneBookSize) { - int size = ((BluetoothPbapRequestPullPhoneBookSize) req).getSize(); - client.sendToClient(EVENT_PULL_PHONE_BOOK_SIZE_DONE, size); - - } else if (req instanceof BluetoothPbapRequestPullVcardListingSize) { - int size = ((BluetoothPbapRequestPullVcardListingSize) req).getSize(); - client.sendToClient(EVENT_PULL_VCARD_LISTING_SIZE_DONE, size); - - } else if (req instanceof BluetoothPbapRequestPullPhoneBook) { - BluetoothPbapRequestPullPhoneBook r = (BluetoothPbapRequestPullPhoneBook) req; - client.sendToClient(EVENT_PULL_PHONE_BOOK_DONE, r.getNewMissedCalls(), - r.getList()); - - } else if (req instanceof BluetoothPbapRequestPullVcardListing) { - BluetoothPbapRequestPullVcardListing r = (BluetoothPbapRequestPullVcardListing) req; - client.sendToClient(EVENT_PULL_VCARD_LISTING_DONE, r.getNewMissedCalls(), - r.getList()); - - } else if (req instanceof BluetoothPbapRequestPullVcardEntry) { - BluetoothPbapRequestPullVcardEntry r = (BluetoothPbapRequestPullVcardEntry) req; - client.sendToClient(EVENT_PULL_VCARD_ENTRY_DONE, r.getVcard()); - - } else if (req instanceof BluetoothPbapRequestSetPath) { - client.sendToClient(EVENT_SET_PHONE_BOOK_DONE); - } - - break; - } - - case BluetoothPbapSession.AUTH_REQUESTED: - client.sendToClient(EVENT_SESSION_AUTH_REQUESTED); - break; - - case BluetoothPbapSession.AUTH_TIMEOUT: - client.sendToClient(EVENT_SESSION_AUTH_TIMEOUT); - break; - - /* - * app does not need to know when session is connected since - * OBEX session is managed inside BluetoothPbapSession - * automatically - we add this only so app can visualize PBAP - * connection status in case it wants to - */ - - case BluetoothPbapSession.SESSION_CONNECTING: - client.mConnectionState = ConnectionState.CONNECTING; - break; - - case BluetoothPbapSession.SESSION_CONNECTED: - client.mConnectionState = ConnectionState.CONNECTED; - client.sendToClient(EVENT_SESSION_CONNECTED); - break; - - case BluetoothPbapSession.SESSION_DISCONNECTED: - client.mConnectionState = ConnectionState.DISCONNECTED; - client.sendToClient(EVENT_SESSION_DISCONNECTED); - break; - } - } - }; - - private void sendToClient(int eventId) { - sendToClient(eventId, 0, null); - } - - private void sendToClient(int eventId, int param) { - sendToClient(eventId, param, null); - } - - private void sendToClient(int eventId, Object param) { - sendToClient(eventId, 0, param); - } - - private void sendToClient(int eventId, int param1, Object param2) { - mClientHandler.obtainMessage(eventId, param1, 0, param2).sendToTarget(); - } - - /** - * Constructs PCE object - * - * @param device BluetoothDevice that corresponds to remote acting in PSE - * role - * @param account the account to which contacts will be added {@see #pullPhoneBook}. - * @param handler the handle that will be used by PCE to notify events and - * results to application - * @throws NullPointerException - */ - public BluetoothPbapClient(BluetoothDevice device, Account account, Handler handler) { - if (DBG) { - Log.d(TAG, " device " + device + " account " + account); - } - if (device == null) { - throw new NullPointerException("BluetoothDevice is null"); - } - - mAccount = account; - - mClientHandler = handler; - - mSessionHandler = new SessionHandler(this); - - mSession = new BluetoothPbapSession(device, mSessionHandler); - } - - /** - * Starts a pbap session. <pb> This method set up rfcomm session, obex - * session and waits for requests to be transfered to PSE. - */ - public void connect() { - mSession.start(); - } - - @Override - public void finalize() { - if (mSession != null) { - mSession.stop(); - } - } - - /** - * Stops all the active transactions and disconnects from the server. - */ - public void disconnect() { - mSession.stop(); - } - - /** - * Aborts current request, if any - */ - public void abort() { - mSession.abort(); - } - - public ConnectionState getState() { - return mConnectionState; - } - - /** - * Sets current folder to root - * - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_SET_PHONE_BOOK_DONE} or - * {@link #EVENT_SET_PHONE_BOOK_ERROR} in case of failure - */ - public boolean setPhoneBookFolderRoot() { - BluetoothPbapRequest req = new BluetoothPbapRequestSetPath(false); - return mSession.makeRequest(req); - } - - /** - * Sets current folder to parent - * - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_SET_PHONE_BOOK_DONE} or - * {@link #EVENT_SET_PHONE_BOOK_ERROR} in case of failure - */ - public boolean setPhoneBookFolderUp() { - BluetoothPbapRequest req = new BluetoothPbapRequestSetPath(true); - return mSession.makeRequest(req); - } - - /** - * Sets current folder to selected sub-folder - * - * @param folder the name of the sub-folder - * @return @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_SET_PHONE_BOOK_DONE} or - * {@link #EVENT_SET_PHONE_BOOK_ERROR} in case of failure - */ - public boolean setPhoneBookFolderDown(String folder) { - BluetoothPbapRequest req = new BluetoothPbapRequestSetPath(folder); - return mSession.makeRequest(req); - } - - /** - * Requests for the number of entries in the phone book. - * - * @param pbName absolute path to the phone book - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_PHONE_BOOK_SIZE_DONE} or - * {@link #EVENT_PULL_PHONE_BOOK_SIZE_ERROR} in case of failure - */ - public boolean pullPhoneBookSize(String pbName) { - BluetoothPbapRequestPullPhoneBookSize req = new BluetoothPbapRequestPullPhoneBookSize( - pbName); - - return mSession.makeRequest(req); - } - - /** - * Requests for the number of entries in the phone book listing. - * - * @param folder the name of the folder to be retrieved - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_VCARD_LISTING_SIZE_DONE} or - * {@link #EVENT_PULL_VCARD_LISTING_SIZE_ERROR} in case of failure - */ - public boolean pullVcardListingSize(String folder) { - BluetoothPbapRequestPullVcardListingSize req = new BluetoothPbapRequestPullVcardListingSize( - folder); - - return mSession.makeRequest(req); - } - - /** - * Pulls complete phone book. This method pulls phone book which entries are - * of <code>VCARD_TYPE_21</code> type and each single vCard contains minimal - * required set of fields and the number of entries in response is not - * limited. - * - * @param pbName absolute path to the phone book - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_PHONE_BOOK_DONE} or - * {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure - */ - public boolean pullPhoneBook(String pbName) { - return pullPhoneBook(pbName, 0, VCARD_TYPE_21, 0, 0); - } - - /** - * Pulls complete phone book. This method pulls all entries from the phone - * book. - * - * @param pbName absolute path to the phone book - * @param filter bit mask which indicates which fields of the vCard shall be - * included in each entry of the resulting list - * @param format vCard format of entries in the resulting list - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_PHONE_BOOK_DONE} or - * {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure - */ - public boolean pullPhoneBook(String pbName, long filter, byte format) { - return pullPhoneBook(pbName, filter, format, 0, 0); - } - - /** - * Pulls complete phone book. This method pulls entries from the phone book - * limited to the number of <code>maxListCount</code> starting from the - * position of <code>listStartOffset</code>. - * <p> - * The resulting list contains vCard objects in version - * <code>VCARD_TYPE_21</code> which in turns contain minimal required set of - * vCard fields. - * - * @param pbName absolute path to the phone book - * @param maxListCount limits number of entries in the response - * @param listStartOffset offset to the first entry of the list that would - * be returned - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_PHONE_BOOK_DONE} or - * {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure - */ - public boolean pullPhoneBook(String pbName, int maxListCount, int listStartOffset) { - return pullPhoneBook(pbName, 0, VCARD_TYPE_21, maxListCount, listStartOffset); - } - - /** - * Pulls complete phone book. - * - * @param pbName absolute path to the phone book - * @param filter bit mask which indicates which fields of the vCard hall be - * included in each entry of the resulting list - * @param format vCard format of entries in the resulting list - * @param maxListCount limits number of entries in the response - * @param listStartOffset offset to the first entry of the list that would - * be returned - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_PHONE_BOOK_DONE} or - * {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure - */ - public boolean pullPhoneBook(String pbName, long filter, byte format, int maxListCount, - int listStartOffset) { - BluetoothPbapRequest req = new BluetoothPbapRequestPullPhoneBook( - pbName, mAccount, filter, format, maxListCount, listStartOffset); - return mSession.makeRequest(req); - } - - /** - * Pulls list of entries in the phone book. - * <p> - * This method pulls the list of entries in the <code>folder</code>. - * - * @param folder the name of the folder to be retrieved - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_VCARD_LISTING_DONE} or - * {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure - */ - public boolean pullVcardListing(String folder) { - return pullVcardListing(folder, ORDER_BY_DEFAULT, SEARCH_ATTR_NAME, null, 0, 0); - } - - /** - * Pulls list of entries in the <code>folder</code>. - * - * @param folder the name of the folder to be retrieved - * @param order the sorting order of the resulting list of entries - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_VCARD_LISTING_DONE} or - * {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure - */ - public boolean pullVcardListing(String folder, byte order) { - return pullVcardListing(folder, order, SEARCH_ATTR_NAME, null, 0, 0); - } - - /** - * Pulls list of entries in the <code>folder</code>. Only entries where - * <code>searchAttr</code> attribute of vCard matches <code>searchVal</code> - * will be listed. - * - * @param folder the name of the folder to be retrieved - * @param searchAttr vCard attribute which shall be used to carry out search - * operation on - * @param searchVal text string used by matching routine to match the value - * of the attribute indicated by SearchAttr - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_VCARD_LISTING_DONE} or - * {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure - */ - public boolean pullVcardListing(String folder, byte searchAttr, String searchVal) { - return pullVcardListing(folder, ORDER_BY_DEFAULT, searchAttr, searchVal, 0, 0); - } - - /** - * Pulls list of entries in the <code>folder</code>. - * - * @param folder the name of the folder to be retrieved - * @param order the sorting order of the resulting list of entries - * @param maxListCount limits number of entries in the response - * @param listStartOffset offset to the first entry of the list that would - * be returned - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_VCARD_LISTING_DONE} or - * {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure - */ - public boolean pullVcardListing(String folder, byte order, int maxListCount, - int listStartOffset) { - return pullVcardListing(folder, order, SEARCH_ATTR_NAME, null, maxListCount, - listStartOffset); - } - - /** - * Pulls list of entries in the <code>folder</code>. - * - * @param folder the name of the folder to be retrieved - * @param maxListCount limits number of entries in the response - * @param listStartOffset offset to the first entry of the list that would - * be returned - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_VCARD_LISTING_DONE} or - * {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure - */ - public boolean pullVcardListing(String folder, int maxListCount, int listStartOffset) { - return pullVcardListing(folder, ORDER_BY_DEFAULT, SEARCH_ATTR_NAME, null, maxListCount, - listStartOffset); - } - - /** - * Pulls list of entries in the <code>folder</code>. - * - * @param folder the name of the folder to be retrieved - * @param order the sorting order of the resulting list of entries - * @param searchAttr vCard attribute which shall be used to carry out search - * operation on - * @param searchVal text string used by matching routine to match the value - * of the attribute indicated by SearchAttr - * @param maxListCount limits number of entries in the response - * @param listStartOffset offset to the first entry of the list that would - * be returned - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_VCARD_LISTING_DONE} or - * {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure - */ - public boolean pullVcardListing(String folder, byte order, byte searchAttr, - String searchVal, int maxListCount, int listStartOffset) { - BluetoothPbapRequest req = new BluetoothPbapRequestPullVcardListing(folder, order, - searchAttr, searchVal, maxListCount, listStartOffset); - return mSession.makeRequest(req); - } - - /** - * Pulls single vCard object - * - * @param handle handle to the vCard which shall be pulled - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_VCARD_DONE} or - * @link #EVENT_PULL_VCARD_ERROR} in case of failure - */ - public boolean pullVcardEntry(String handle) { - return pullVcardEntry(handle, (byte) 0, VCARD_TYPE_21); - } - - /** - * Pulls single vCard object - * - * @param handle handle to the vCard which shall be pulled - * @param filter bit mask of the vCard fields that shall be included in the - * resulting vCard - * @param format resulting vCard version - * @return <code>true</code> if request has been sent successfully; - * <code>false</code> otherwise; upon completion PCE sends - * {@link #EVENT_PULL_VCARD_DONE} - * @link #EVENT_PULL_VCARD_ERROR} in case of failure - */ - public boolean pullVcardEntry(String handle, long filter, byte format) { - BluetoothPbapRequest req = - new BluetoothPbapRequestPullVcardEntry(handle, mAccount, filter, format); - return mSession.makeRequest(req); - } - - public boolean setAuthResponse(String key) { - Log.d(TAG, " setAuthResponse key=" + key); - return mSession.setAuthResponse(key); - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapObexAuthenticator.java b/src/android/bluetooth/client/pbap/BluetoothPbapObexAuthenticator.java deleted file mode 100644 index 9402e81..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapObexAuthenticator.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.os.Handler; -import android.util.Log; - -import javax.obex.Authenticator; -import javax.obex.PasswordAuthentication; - -class BluetoothPbapObexAuthenticator implements Authenticator { - - private final static String TAG = "BluetoothPbapObexAuthenticator"; - - private String mSessionKey; - - private boolean mReplied; - - private final Handler mCallback; - - public BluetoothPbapObexAuthenticator(Handler callback) { - mCallback = callback; - } - - public synchronized void setReply(String key) { - Log.d(TAG, "setReply key=" + key); - - mSessionKey = key; - mReplied = true; - - notify(); - } - - @Override - public PasswordAuthentication onAuthenticationChallenge(String description, - boolean isUserIdRequired, boolean isFullAccess) { - PasswordAuthentication pa = null; - - mReplied = false; - - Log.d(TAG, "onAuthenticationChallenge: sending request"); - mCallback.obtainMessage(BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_REQUEST) - .sendToTarget(); - - synchronized (this) { - while (!mReplied) { - try { - Log.v(TAG, "onAuthenticationChallenge: waiting for response"); - this.wait(); - } catch (InterruptedException e) { - Log.e(TAG, "Interrupted while waiting for challenge response"); - } - } - } - - if (mSessionKey != null && mSessionKey.length() != 0) { - Log.v(TAG, "onAuthenticationChallenge: mSessionKey=" + mSessionKey); - pa = new PasswordAuthentication(null, mSessionKey.getBytes()); - } else { - Log.v(TAG, "onAuthenticationChallenge: mSessionKey is empty, timeout/cancel occured"); - } - - return pa; - } - - @Override - public byte[] onAuthenticationResponse(byte[] userName) { - /* required only in case PCE challenges PSE which we don't do now */ - return null; - } - -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapObexSession.java b/src/android/bluetooth/client/pbap/BluetoothPbapObexSession.java deleted file mode 100644 index 48b240c..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapObexSession.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import java.io.IOException; -import java.lang.ref.WeakReference; - -import javax.obex.ClientSession; -import javax.obex.HeaderSet; -import javax.obex.ObexTransport; -import javax.obex.ResponseCodes; - -final class BluetoothPbapObexSession { - private static final boolean DBG = true; - private static final String TAG = "BluetoothPbapObexSession"; - - private static final byte[] PBAP_TARGET = new byte[] { - 0x79, 0x61, 0x35, (byte) 0xf0, (byte) 0xf0, (byte) 0xc5, 0x11, (byte) 0xd8, 0x09, 0x66, - 0x08, 0x00, 0x20, 0x0c, (byte) 0x9a, 0x66 - }; - - final static int OBEX_SESSION_CONNECTED = 100; - final static int OBEX_SESSION_FAILED = 101; - final static int OBEX_SESSION_DISCONNECTED = 102; - final static int OBEX_SESSION_REQUEST_COMPLETED = 103; - final static int OBEX_SESSION_REQUEST_FAILED = 104; - final static int OBEX_SESSION_AUTHENTICATION_REQUEST = 105; - final static int OBEX_SESSION_AUTHENTICATION_TIMEOUT = 106; - - final static int MSG_CONNECT = 0; - final static int MSG_REQUEST = 1; - - final static int CONNECTED = 0; - final static int CONNECTING = 1; - final static int DISCONNECTED = 2; - - private Handler mSessionHandler; - private final ObexTransport mTransport; - // private ObexClientThread mObexClientThread; - private BluetoothPbapObexAuthenticator mAuth = null; - private HandlerThread mThread; - private Handler mHandler; - private ClientSession mClientSession; - - private int mState = DISCONNECTED; - - public BluetoothPbapObexSession(ObexTransport transport) { - mTransport = transport; - } - - public synchronized boolean start(Handler handler) { - Log.d(TAG, "start"); - - if (mState == CONNECTED || mState == CONNECTING) { - return false; - } - mState = CONNECTING; - mSessionHandler = handler; - - mAuth = new BluetoothPbapObexAuthenticator(mSessionHandler); - - // Start the thread to process requests (see {@link schedule()}. - mThread = new HandlerThread("BluetoothPbapObexSessionThread"); - mThread.start(); - mHandler = new ObexClientHandler(mThread.getLooper(), this); - - // Make connect call non blocking. - boolean status = mHandler.sendMessage(mHandler.obtainMessage(MSG_CONNECT)); - if (!status) { - mState = DISCONNECTED; - return false; - } else { - return true; - } - } - - public void stop() { - if (DBG) { - Log.d(TAG, "stop"); - } - - // This will essentially stop the handler and ignore any inflight requests. - mThread.quit(); - - // We clean up the state here. - disconnect(false /* no callback */); - } - - public void abort() { - stop(); - } - - public boolean schedule(BluetoothPbapRequest request) { - if (DBG) { - Log.d(TAG, "schedule() called with: " + request); - } - - boolean status = mHandler.sendMessage(mHandler.obtainMessage(MSG_REQUEST, request)); - if (!status) { - Log.e(TAG, "Adding messages failed, obex must be disconnected."); - return false; - } - return true; - } - - public int isConnected() { - return mState; - } - - private void connect() { - if (DBG) { - Log.d(TAG, "connect()"); - } - - boolean success = true; - try { - mClientSession = new ClientSession(mTransport); - mClientSession.setAuthenticator(mAuth); - } catch (IOException e) { - Log.d(TAG, "connect() exception: " + e); - success = false; - } - - HeaderSet hs = new HeaderSet(); - hs.setHeader(HeaderSet.TARGET, PBAP_TARGET); - try { - hs = mClientSession.connect(hs); - - if (hs.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) { - disconnect(true /* callback */); - success = false; - } - } catch (IOException e) { - success = false; - } - - synchronized (this) { - if (success) { - mSessionHandler.obtainMessage(OBEX_SESSION_CONNECTED).sendToTarget(); - mState = CONNECTED; - } else { - mSessionHandler.obtainMessage(OBEX_SESSION_DISCONNECTED).sendToTarget(); - mState = DISCONNECTED; - } - } - } - - private synchronized void disconnect(boolean callback) { - if (DBG) { - Log.d(TAG, "disconnect()"); - } - - if (mState != DISCONNECTED) { - return; - } - - if (mClientSession != null) { - try { - mClientSession.disconnect(null); - mClientSession.close(); - } catch (IOException e) { - } - } - - if (callback) { - mSessionHandler.obtainMessage(OBEX_SESSION_DISCONNECTED).sendToTarget(); - } - - mState = DISCONNECTED; - } - - private void executeRequest(BluetoothPbapRequest req) { - try { - req.execute(mClientSession); - } catch (IOException e) { - Log.e(TAG, "Error during executeRequest " + e); - disconnect(true); - } - - if (req.isSuccess()) { - mSessionHandler.obtainMessage(OBEX_SESSION_REQUEST_COMPLETED, req).sendToTarget(); - } else { - mSessionHandler.obtainMessage(OBEX_SESSION_REQUEST_FAILED, req).sendToTarget(); - } - } - - public boolean setAuthReply(String key) { - Log.d(TAG, "setAuthReply key=" + key); - - if (mAuth == null) { - return false; - } - - mAuth.setReply(key); - - return true; - } - - private static class ObexClientHandler extends Handler { - WeakReference<BluetoothPbapObexSession> mInst; - - ObexClientHandler(Looper looper, BluetoothPbapObexSession inst) { - super(looper); - mInst = new WeakReference<BluetoothPbapObexSession>(inst); - } - - @Override - public void handleMessage(Message msg) { - BluetoothPbapObexSession inst = mInst.get(); - if (inst == null) { - Log.e(TAG, "The instance class is no longer around; terminating."); - return; - } - - if (inst.isConnected() != CONNECTED && msg.what != MSG_CONNECT) { - Log.w(TAG, "Cannot execute " + msg + " when not CONNECTED."); - return; - } - - switch (msg.what) { - case MSG_CONNECT: - inst.connect(); - break; - case MSG_REQUEST: - inst.executeRequest((BluetoothPbapRequest) msg.obj); - break; - default: - Log.e(TAG, "Unknwown message type: " + msg.what); - } - } - } -} - diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapObexTransport.java b/src/android/bluetooth/client/pbap/BluetoothPbapObexTransport.java deleted file mode 100644 index 674c66f..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapObexTransport.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.bluetooth.BluetoothSocket; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.obex.ObexTransport; - -class BluetoothPbapObexTransport implements ObexTransport { - - private BluetoothSocket mSocket = null; - - public BluetoothPbapObexTransport(BluetoothSocket rfs) { - super(); - mSocket = rfs; - } - - @Override - public void close() throws IOException { - mSocket.close(); - } - - @Override - public DataInputStream openDataInputStream() throws IOException { - return new DataInputStream(openInputStream()); - } - - @Override - public DataOutputStream openDataOutputStream() throws IOException { - return new DataOutputStream(openOutputStream()); - } - - @Override - public InputStream openInputStream() throws IOException { - return mSocket.getInputStream(); - } - - @Override - public OutputStream openOutputStream() throws IOException { - return mSocket.getOutputStream(); - } - - @Override - public void connect() throws IOException { - } - - @Override - public void create() throws IOException { - } - - @Override - public void disconnect() throws IOException { - } - - @Override - public void listen() throws IOException { - } - - public boolean isConnected() throws IOException { - // return true; - return mSocket.isConnected(); - } - - @Override - public int getMaxTransmitPacketSize() { - return -1; - } - - @Override - public int getMaxReceivePacketSize() { - return -1; - } - - @Override - public boolean isSrmSupported() { - return false; - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequest.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequest.java deleted file mode 100644 index 0974c75..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapRequest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.util.Log; - -import java.io.IOException; -import java.io.InputStream; - -import javax.obex.ClientOperation; -import javax.obex.ClientSession; -import javax.obex.HeaderSet; -import javax.obex.ResponseCodes; - -abstract class BluetoothPbapRequest { - - private static final String TAG = "BluetoothPbapRequest"; - - protected static final byte OAP_TAGID_ORDER = 0x01; - protected static final byte OAP_TAGID_SEARCH_VALUE = 0x02; - protected static final byte OAP_TAGID_SEARCH_ATTRIBUTE = 0x03; - protected static final byte OAP_TAGID_MAX_LIST_COUNT = 0x04; - protected static final byte OAP_TAGID_LIST_START_OFFSET = 0x05; - protected static final byte OAP_TAGID_FILTER = 0x06; - protected static final byte OAP_TAGID_FORMAT = 0x07; - protected static final byte OAP_TAGID_PHONEBOOK_SIZE = 0x08; - protected static final byte OAP_TAGID_NEW_MISSED_CALLS = 0x09; - - protected HeaderSet mHeaderSet; - - protected int mResponseCode; - - private boolean mAborted = false; - - private ClientOperation mOp = null; - - public BluetoothPbapRequest() { - mHeaderSet = new HeaderSet(); - } - - final public boolean isSuccess() { - return (mResponseCode == ResponseCodes.OBEX_HTTP_OK); - } - - public void execute(ClientSession session) throws IOException { - Log.v(TAG, "execute"); - - /* in case request is aborted before can be executed */ - if (mAborted) { - mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; - return; - } - - try { - mOp = (ClientOperation) session.get(mHeaderSet); - - /* make sure final flag for GET is used (PBAP spec 6.2.2) */ - mOp.setGetFinalFlag(true); - - /* - * this will trigger ClientOperation to use non-buffered stream so - * we can abort operation - */ - mOp.continueOperation(true, false); - - readResponseHeaders(mOp.getReceivedHeader()); - - InputStream is = mOp.openInputStream(); - readResponse(is); - is.close(); - - mOp.close(); - - mResponseCode = mOp.getResponseCode(); - - Log.d(TAG, "mResponseCode=" + mResponseCode); - - checkResponseCode(mResponseCode); - } catch (IOException e) { - Log.e(TAG, "IOException occured when processing request", e); - mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; - - throw e; - } - } - - public void abort() { - mAborted = true; - - if (mOp != null) { - try { - mOp.abort(); - } catch (IOException e) { - Log.e(TAG, "Exception occured when trying to abort", e); - } - } - } - - protected void readResponse(InputStream stream) throws IOException { - Log.v(TAG, "readResponse"); - - /* nothing here by default */ - } - - protected void readResponseHeaders(HeaderSet headerset) { - Log.v(TAG, "readResponseHeaders"); - - /* nothing here by dafault */ - } - - protected void checkResponseCode(int responseCode) throws IOException { - Log.v(TAG, "checkResponseCode"); - - /* nothing here by dafault */ - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java deleted file mode 100644 index 411a8de..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.accounts.Account; -import android.util.Log; - -import com.android.vcard.VCardEntry; -import android.bluetooth.client.pbap.utils.ObexAppParameters; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -import javax.obex.HeaderSet; - -final class BluetoothPbapRequestPullPhoneBook extends BluetoothPbapRequest { - - private static final boolean DBG = true; - - private static final String TAG = "BluetoothPbapRequestPullPhoneBook"; - - private static final String TYPE = "x-bt/phonebook"; - - private BluetoothPbapVcardList mResponse; - - private Account mAccount; - - private int mNewMissedCalls = -1; - - private final byte mFormat; - - public BluetoothPbapRequestPullPhoneBook( - String pbName, Account account, long filter, byte format, - int maxListCount, int listStartOffset) { - mAccount = account; - if (maxListCount < 0 || maxListCount > 65535) { - throw new IllegalArgumentException("maxListCount should be [0..65535]"); - } - - if (listStartOffset < 0 || listStartOffset > 65535) { - throw new IllegalArgumentException("listStartOffset should be [0..65535]"); - } - - mHeaderSet.setHeader(HeaderSet.NAME, pbName); - - mHeaderSet.setHeader(HeaderSet.TYPE, TYPE); - - ObexAppParameters oap = new ObexAppParameters(); - - /* make sure format is one of allowed values */ - if (format != BluetoothPbapClient.VCARD_TYPE_21 - && format != BluetoothPbapClient.VCARD_TYPE_30) { - format = BluetoothPbapClient.VCARD_TYPE_21; - } - - if (filter != 0) { - oap.add(OAP_TAGID_FILTER, filter); - } - - oap.add(OAP_TAGID_FORMAT, format); - - /* - * maxListCount is a special case which is handled in - * BluetoothPbapRequestPullPhoneBookSize - */ - if (maxListCount > 0) { - oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) maxListCount); - } else { - oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) 65535); - } - - if (listStartOffset > 0) { - oap.add(OAP_TAGID_LIST_START_OFFSET, (short) listStartOffset); - } - - oap.addToHeaderSet(mHeaderSet); - - mFormat = format; - } - - @Override - protected void readResponse(InputStream stream) throws IOException { - Log.v(TAG, "readResponse"); - - mResponse = new BluetoothPbapVcardList(mAccount, stream, mFormat); - if (DBG) { - Log.d(TAG, "Read " + mResponse.getCount() + " entries."); - } - } - - @Override - protected void readResponseHeaders(HeaderSet headerset) { - Log.v(TAG, "readResponseHeaders"); - - ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset); - - if (oap.exists(OAP_TAGID_NEW_MISSED_CALLS)) { - mNewMissedCalls = oap.getByte(OAP_TAGID_NEW_MISSED_CALLS); - } - } - - public ArrayList<VCardEntry> getList() { - return mResponse.getList(); - } - - public int getNewMissedCalls() { - return mNewMissedCalls; - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBookSize.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBookSize.java deleted file mode 100644 index 664f081..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBookSize.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.util.Log; - -import android.bluetooth.client.pbap.utils.ObexAppParameters; - -import javax.obex.HeaderSet; - -class BluetoothPbapRequestPullPhoneBookSize extends BluetoothPbapRequest { - - private static final String TAG = "BluetoothPbapRequestPullPhoneBookSize"; - - private static final String TYPE = "x-bt/phonebook"; - - private int mSize; - - public BluetoothPbapRequestPullPhoneBookSize(String pbName) { - mHeaderSet.setHeader(HeaderSet.NAME, pbName); - - mHeaderSet.setHeader(HeaderSet.TYPE, TYPE); - - ObexAppParameters oap = new ObexAppParameters(); - oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) 0); - oap.addToHeaderSet(mHeaderSet); - } - - @Override - protected void readResponseHeaders(HeaderSet headerset) { - Log.v(TAG, "readResponseHeaders"); - - ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset); - - mSize = oap.getShort(OAP_TAGID_PHONEBOOK_SIZE); - } - - public int getSize() { - return mSize; - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java deleted file mode 100644 index ed823d5..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.accounts.Account; -import android.util.Log; - -import com.android.vcard.VCardEntry; -import android.bluetooth.client.pbap.utils.ObexAppParameters; - -import java.io.IOException; -import java.io.InputStream; - -import javax.obex.HeaderSet; -import javax.obex.ResponseCodes; - -final class BluetoothPbapRequestPullVcardEntry extends BluetoothPbapRequest { - - private static final String TAG = "BluetoothPbapRequestPullVcardEntry"; - - private static final String TYPE = "x-bt/vcard"; - - private BluetoothPbapVcardList mResponse; - - private final Account mAccount; - - private final byte mFormat; - - public BluetoothPbapRequestPullVcardEntry( - String handle, Account account, long filter, byte format) { - mAccount = account; - - mHeaderSet.setHeader(HeaderSet.NAME, handle); - - mHeaderSet.setHeader(HeaderSet.TYPE, TYPE); - - /* make sure format is one of allowed values */ - if (format != BluetoothPbapClient.VCARD_TYPE_21 - && format != BluetoothPbapClient.VCARD_TYPE_30) { - format = BluetoothPbapClient.VCARD_TYPE_21; - } - - ObexAppParameters oap = new ObexAppParameters(); - - if (filter != 0) { - oap.add(OAP_TAGID_FILTER, filter); - } - - oap.add(OAP_TAGID_FORMAT, format); - oap.addToHeaderSet(mHeaderSet); - - mFormat = format; - } - - @Override - protected void readResponse(InputStream stream) throws IOException { - Log.v(TAG, "readResponse"); - - mResponse = new BluetoothPbapVcardList(mAccount, stream, mFormat); - } - @Override - protected void checkResponseCode(int responseCode) throws IOException { - Log.v(TAG, "checkResponseCode"); - - if (mResponse.getCount() == 0) { - if (responseCode != ResponseCodes.OBEX_HTTP_NOT_FOUND && - responseCode != ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE) { - throw new IOException("Invalid response received"); - } else { - Log.v(TAG, "Vcard Entry not found"); - } - } - } - - public VCardEntry getVcard() { - return mResponse.getFirst(); - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListing.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListing.java deleted file mode 100644 index 5f042ba..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListing.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.util.Log; - -import android.bluetooth.client.pbap.utils.ObexAppParameters; -import android.bluetooth.client.pbap.BluetoothPbapVcardListing; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -import javax.obex.HeaderSet; - -final class BluetoothPbapRequestPullVcardListing extends BluetoothPbapRequest { - - private static final String TAG = "BluetoothPbapRequestPullVcardListing"; - - private static final String TYPE = "x-bt/vcard-listing"; - - private BluetoothPbapVcardListing mResponse = null; - - private int mNewMissedCalls = -1; - - public BluetoothPbapRequestPullVcardListing(String folder, byte order, byte searchAttr, - String searchVal, int maxListCount, int listStartOffset) { - - if (maxListCount < 0 || maxListCount > 65535) { - throw new IllegalArgumentException("maxListCount should be [0..65535]"); - } - - if (listStartOffset < 0 || listStartOffset > 65535) { - throw new IllegalArgumentException("listStartOffset should be [0..65535]"); - } - - if (folder == null) { - folder = ""; - } - - mHeaderSet.setHeader(HeaderSet.NAME, folder); - - mHeaderSet.setHeader(HeaderSet.TYPE, TYPE); - - ObexAppParameters oap = new ObexAppParameters(); - - if (order >= 0) { - oap.add(OAP_TAGID_ORDER, order); - } - - if (searchVal != null) { - oap.add(OAP_TAGID_SEARCH_ATTRIBUTE, searchAttr); - oap.add(OAP_TAGID_SEARCH_VALUE, searchVal); - } - - /* - * maxListCount is a special case which is handled in - * BluetoothPbapRequestPullVcardListingSize - */ - if (maxListCount > 0) { - oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) maxListCount); - } - - if (listStartOffset > 0) { - oap.add(OAP_TAGID_LIST_START_OFFSET, (short) listStartOffset); - } - - oap.addToHeaderSet(mHeaderSet); - } - - @Override - protected void readResponse(InputStream stream) throws IOException { - Log.v(TAG, "readResponse"); - - mResponse = new BluetoothPbapVcardListing(stream); - } - - @Override - protected void readResponseHeaders(HeaderSet headerset) { - Log.v(TAG, "readResponseHeaders"); - - ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset); - - if (oap.exists(OAP_TAGID_NEW_MISSED_CALLS)) { - mNewMissedCalls = oap.getByte(OAP_TAGID_NEW_MISSED_CALLS); - } - } - - public ArrayList<BluetoothPbapCard> getList() { - return mResponse.getList(); - } - - public int getNewMissedCalls() { - return mNewMissedCalls; - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListingSize.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListingSize.java deleted file mode 100644 index ab276c3..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListingSize.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.util.Log; - -import android.bluetooth.client.pbap.utils.ObexAppParameters; - -import javax.obex.HeaderSet; - -class BluetoothPbapRequestPullVcardListingSize extends BluetoothPbapRequest { - - private static final String TAG = "BluetoothPbapRequestPullVcardListingSize"; - - private static final String TYPE = "x-bt/vcard-listing"; - - private int mSize; - - public BluetoothPbapRequestPullVcardListingSize(String folder) { - mHeaderSet.setHeader(HeaderSet.NAME, folder); - - mHeaderSet.setHeader(HeaderSet.TYPE, TYPE); - - ObexAppParameters oap = new ObexAppParameters(); - oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) 0); - oap.addToHeaderSet(mHeaderSet); - } - - @Override - protected void readResponseHeaders(HeaderSet headerset) { - Log.v(TAG, "readResponseHeaders"); - - ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset); - - mSize = oap.getShort(OAP_TAGID_PHONEBOOK_SIZE); - } - - public int getSize() { - return mSize; - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestSetPath.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestSetPath.java deleted file mode 100644 index 60f5244..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapRequestSetPath.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.util.Log; - -import java.io.IOException; - -import javax.obex.ClientSession; -import javax.obex.HeaderSet; -import javax.obex.ResponseCodes; - -final class BluetoothPbapRequestSetPath extends BluetoothPbapRequest { - - private final static String TAG = "BluetoothPbapRequestSetPath"; - - private enum SetPathDir { - ROOT, UP, DOWN - }; - - private SetPathDir mDir; - - public BluetoothPbapRequestSetPath(String name) { - mDir = SetPathDir.DOWN; - mHeaderSet.setHeader(HeaderSet.NAME, name); - } - - public BluetoothPbapRequestSetPath(boolean goUp) { - mHeaderSet.setEmptyNameHeader(); - if (goUp) { - mDir = SetPathDir.UP; - } else { - mDir = SetPathDir.ROOT; - } - } - - @Override - public void execute(ClientSession session) { - Log.v(TAG, "execute"); - - HeaderSet hs = null; - - try { - switch (mDir) { - case ROOT: - case DOWN: - hs = session.setPath(mHeaderSet, false, false); - break; - case UP: - hs = session.setPath(mHeaderSet, true, false); - break; - } - - mResponseCode = hs.getResponseCode(); - } catch (IOException e) { - mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; - } - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapSession.java b/src/android/bluetooth/client/pbap/BluetoothPbapSession.java deleted file mode 100644 index faafd0b..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapSession.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothSocket; -import android.os.Handler; -import android.os.Handler.Callback; -import android.os.HandlerThread; -import android.os.Message; -import android.os.Process; -import android.util.Log; - -import java.io.IOException; -import java.util.UUID; - -class BluetoothPbapSession implements Callback { - private static final String TAG = "android.bluetooth.client.pbap.BluetoothPbapSession"; - - /* local use only */ - private static final int RFCOMM_CONNECTED = 1; - private static final int RFCOMM_FAILED = 2; - - /* to BluetoothPbapClient */ - public static final int REQUEST_COMPLETED = 3; - public static final int REQUEST_FAILED = 4; - public static final int SESSION_CONNECTING = 5; - public static final int SESSION_CONNECTED = 6; - public static final int SESSION_DISCONNECTED = 7; - public static final int AUTH_REQUESTED = 8; - public static final int AUTH_TIMEOUT = 9; - - public static final int ACTION_LISTING = 14; - public static final int ACTION_VCARD = 15; - public static final int ACTION_PHONEBOOK_SIZE = 16; - - private static final String PBAP_UUID = - "0000112f-0000-1000-8000-00805f9b34fb"; - - private final BluetoothAdapter mAdapter; - private final BluetoothDevice mDevice; - - private final Handler mParentHandler; - - private final HandlerThread mHandlerThread; - private final Handler mSessionHandler; - - private RfcommConnectThread mConnectThread; - private BluetoothPbapObexTransport mTransport; - - private BluetoothPbapObexSession mObexSession; - - private BluetoothPbapRequest mPendingRequest = null; - - public BluetoothPbapSession(BluetoothDevice device, Handler handler) { - - mAdapter = BluetoothAdapter.getDefaultAdapter(); - if (mAdapter == null) { - throw new NullPointerException("No Bluetooth adapter in the system"); - } - - mDevice = device; - mParentHandler = handler; - mConnectThread = null; - mTransport = null; - mObexSession = null; - - mHandlerThread = new HandlerThread("PBAP session handler", - Process.THREAD_PRIORITY_BACKGROUND); - mHandlerThread.start(); - mSessionHandler = new Handler(mHandlerThread.getLooper(), this); - } - - @Override - public boolean handleMessage(Message msg) { - Log.d(TAG, "Handler: msg: " + msg.what); - - switch (msg.what) { - case RFCOMM_FAILED: - mConnectThread = null; - - mParentHandler.obtainMessage(SESSION_DISCONNECTED).sendToTarget(); - - if (mPendingRequest != null) { - mParentHandler.obtainMessage(REQUEST_FAILED, mPendingRequest).sendToTarget(); - mPendingRequest = null; - } - break; - - case RFCOMM_CONNECTED: - mConnectThread = null; - mTransport = (BluetoothPbapObexTransport) msg.obj; - startObexSession(); - break; - - case BluetoothPbapObexSession.OBEX_SESSION_FAILED: - stopObexSession(); - - mParentHandler.obtainMessage(SESSION_DISCONNECTED).sendToTarget(); - - if (mPendingRequest != null) { - mParentHandler.obtainMessage(REQUEST_FAILED, mPendingRequest).sendToTarget(); - mPendingRequest = null; - } - break; - - case BluetoothPbapObexSession.OBEX_SESSION_CONNECTED: - mParentHandler.obtainMessage(SESSION_CONNECTED).sendToTarget(); - - if (mPendingRequest != null) { - mObexSession.schedule(mPendingRequest); - mPendingRequest = null; - } - break; - - case BluetoothPbapObexSession.OBEX_SESSION_DISCONNECTED: - mParentHandler.obtainMessage(SESSION_DISCONNECTED).sendToTarget(); - stopRfcomm(); - break; - - case BluetoothPbapObexSession.OBEX_SESSION_REQUEST_COMPLETED: - /* send to parent, process there */ - mParentHandler.obtainMessage(REQUEST_COMPLETED, msg.obj).sendToTarget(); - break; - - case BluetoothPbapObexSession.OBEX_SESSION_REQUEST_FAILED: - /* send to parent, process there */ - mParentHandler.obtainMessage(REQUEST_FAILED, msg.obj).sendToTarget(); - break; - - case BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_REQUEST: - /* send to parent, process there */ - mParentHandler.obtainMessage(AUTH_REQUESTED).sendToTarget(); - - mSessionHandler - .sendMessageDelayed( - mSessionHandler - .obtainMessage(BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_TIMEOUT), - 30000); - break; - - case BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_TIMEOUT: - /* stop authentication */ - setAuthResponse(null); - - mParentHandler.obtainMessage(AUTH_TIMEOUT).sendToTarget(); - break; - - default: - return false; - } - - return true; - } - - public void start() { - Log.d(TAG, "start"); - - startRfcomm(); - } - - public void stop() { - Log.d(TAG, "Stop"); - - stopObexSession(); - stopRfcomm(); - } - - public void abort() { - Log.d(TAG, "abort"); - - /* fail pending request immediately */ - if (mPendingRequest != null) { - mParentHandler.obtainMessage(REQUEST_FAILED, mPendingRequest).sendToTarget(); - mPendingRequest = null; - } - - if (mObexSession != null) { - mObexSession.abort(); - } - } - - public boolean makeRequest(BluetoothPbapRequest request) { - Log.v(TAG, "makeRequest: " + request.getClass().getSimpleName()); - - if (mPendingRequest != null) { - Log.w(TAG, "makeRequest: request already queued, exiting"); - return false; - } - - if (mObexSession == null) { - mPendingRequest = request; - - /* - * since there is no pending request and no session it's safe to - * assume that RFCOMM does not exist either and we should start - * connecting it - */ - startRfcomm(); - - return true; - } - - return mObexSession.schedule(request); - } - - public boolean setAuthResponse(String key) { - Log.d(TAG, "setAuthResponse key=" + key); - - mSessionHandler - .removeMessages(BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_TIMEOUT); - - /* does not make sense to set auth response when OBEX session is down */ - if (mObexSession == null) { - return false; - } - - return mObexSession.setAuthReply(key); - } - - private void startRfcomm() { - Log.d(TAG, "startRfcomm"); - - if (mConnectThread == null && mObexSession == null) { - mParentHandler.obtainMessage(SESSION_CONNECTING).sendToTarget(); - - mConnectThread = new RfcommConnectThread(); - mConnectThread.start(); - } - - /* - * don't care if mConnectThread is not null - it means RFCOMM is being - * connected anyway - */ - } - - private void stopRfcomm() { - Log.d(TAG, "stopRfcomm"); - - if (mConnectThread != null) { - try { - // Force close the socket in case the thread is stuck doing the connect() - // call. - mConnectThread.closeSocket(); - // TODO: Add timed join if closeSocket does not clean up the state. - mConnectThread.join(); - } catch (InterruptedException e) { - } - - mConnectThread = null; - } - - if (mTransport != null) { - try { - mTransport.close(); - } catch (IOException e) { - } - - mTransport = null; - } - } - - private void startObexSession() { - Log.d(TAG, "startObexSession"); - - mObexSession = new BluetoothPbapObexSession(mTransport); - mObexSession.start(mSessionHandler); - } - - private void stopObexSession() { - Log.d(TAG, "stopObexSession"); - - if (mObexSession != null) { - mObexSession.stop(); - mObexSession = null; - } - } - - private class RfcommConnectThread extends Thread { - private static final String TAG = "RfcommConnectThread"; - - private BluetoothSocket mSocket; - - public RfcommConnectThread() { - super("RfcommConnectThread"); - } - - @Override - public void run() { - if (mAdapter.isDiscovering()) { - mAdapter.cancelDiscovery(); - } - - try { - mSocket = mDevice.createRfcommSocketToServiceRecord(UUID.fromString(PBAP_UUID)); - mSocket.connect(); - - BluetoothPbapObexTransport transport; - transport = new BluetoothPbapObexTransport(mSocket); - - mSessionHandler.obtainMessage(RFCOMM_CONNECTED, transport).sendToTarget(); - } catch (IOException e) { - closeSocket(); - mSessionHandler.obtainMessage(RFCOMM_FAILED).sendToTarget(); - } - - } - - // This method may be called from outside the thread if the connect() call above is stuck. - public void closeSocket() { - try { - if (mSocket != null) { - mSocket.close(); - } - } catch (IOException e) { - Log.e(TAG, "Error when closing socket", e); - } - } - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java b/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java deleted file mode 100644 index 6bc75de..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.accounts.Account; - -import com.android.vcard.VCardConfig; -import com.android.vcard.VCardEntry; -import com.android.vcard.VCardEntryConstructor; -import com.android.vcard.VCardEntryCounter; -import com.android.vcard.VCardEntryHandler; -import com.android.vcard.VCardParser; -import com.android.vcard.VCardParser_V21; -import com.android.vcard.VCardParser_V30; -import com.android.vcard.exception.VCardException; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -class BluetoothPbapVcardList { - - private final ArrayList<VCardEntry> mCards = new ArrayList<VCardEntry>(); - private final Account mAccount; - - class CardEntryHandler implements VCardEntryHandler { - @Override - public void onStart() { - } - - @Override - public void onEntryCreated(VCardEntry entry) { - mCards.add(entry); - } - - @Override - public void onEnd() { - } - } - - public BluetoothPbapVcardList(Account account, InputStream in, byte format) throws IOException { - mAccount = account; - parse(in, format); - } - - private void parse(InputStream in, byte format) throws IOException { - VCardParser parser; - - if (format == BluetoothPbapClient.VCARD_TYPE_30) { - parser = new VCardParser_V30(); - } else { - parser = new VCardParser_V21(); - } - - VCardEntryConstructor constructor = - new VCardEntryConstructor(VCardConfig.VCARD_TYPE_V21_GENERIC, mAccount); - VCardEntryCounter counter = new VCardEntryCounter(); - CardEntryHandler handler = new CardEntryHandler(); - - constructor.addEntryHandler(handler); - - parser.addInterpreter(constructor); - parser.addInterpreter(counter); - - try { - parser.parse(in); - } catch (VCardException e) { - e.printStackTrace(); - } - } - - public int getCount() { - return mCards.size(); - } - - public ArrayList<VCardEntry> getList() { - return mCards; - } - - public VCardEntry getFirst() { - return mCards.get(0); - } -} diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapVcardListing.java b/src/android/bluetooth/client/pbap/BluetoothPbapVcardListing.java deleted file mode 100644 index d963c94..0000000 --- a/src/android/bluetooth/client/pbap/BluetoothPbapVcardListing.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap; - -import android.util.Log; -import android.util.Xml; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -class BluetoothPbapVcardListing { - - private static final String TAG = "BluetoothPbapVcardListing"; - - ArrayList<BluetoothPbapCard> mCards = new ArrayList<BluetoothPbapCard>(); - - public BluetoothPbapVcardListing(InputStream in) throws IOException { - parse(in); - } - - private void parse(InputStream in) throws IOException { - XmlPullParser parser = Xml.newPullParser(); - - try { - parser.setInput(in, "UTF-8"); - - int eventType = parser.getEventType(); - - while (eventType != XmlPullParser.END_DOCUMENT) { - - if (eventType == XmlPullParser.START_TAG && parser.getName().equals("card")) { - BluetoothPbapCard card = new BluetoothPbapCard( - parser.getAttributeValue(null, "handle"), - parser.getAttributeValue(null, "name")); - mCards.add(card); - } - - eventType = parser.next(); - } - } catch (XmlPullParserException e) { - Log.e(TAG, "XML parser error when parsing XML", e); - } - } - - public ArrayList<BluetoothPbapCard> getList() { - return mCards; - } -} diff --git a/src/android/bluetooth/client/pbap/utils/BmsgTokenizer.java b/src/android/bluetooth/client/pbap/utils/BmsgTokenizer.java deleted file mode 100644 index cf138c9..0000000 --- a/src/android/bluetooth/client/pbap/utils/BmsgTokenizer.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap.utils; - -import android.util.Log; - -import java.text.ParseException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public final class BmsgTokenizer { - - private final String mStr; - - private final Matcher mMatcher; - - private int mPos = 0; - - private final int mOffset; - - static public class Property { - public final String name; - public final String value; - - public Property(String name, String value) { - if (name == null || value == null) { - throw new IllegalArgumentException(); - } - - this.name = name; - this.value = value; - - Log.v("BMSG >> ", toString()); - } - - @Override - public String toString() { - return name + ":" + value; - } - - @Override - public boolean equals(Object o) { - return ((o instanceof Property) && ((Property) o).name.equals(name) && ((Property) o).value - .equals(value)); - } - }; - - public BmsgTokenizer(String str) { - this(str, 0); - } - - public BmsgTokenizer(String str, int offset) { - mStr = str; - mOffset = offset; - mMatcher = Pattern.compile("(([^:]*):(.*))?\r\n").matcher(str); - mPos = mMatcher.regionStart(); - } - - public Property next(boolean alwaysReturn) throws ParseException { - boolean found = false; - - do { - mMatcher.region(mPos, mMatcher.regionEnd()); - - if (!mMatcher.lookingAt()) { - if (alwaysReturn) { - return null; - } - - throw new ParseException("Property or empty line expected", pos()); - } - - mPos = mMatcher.end(); - - if (mMatcher.group(1) != null) { - found = true; - } - } while (!found); - - return new Property(mMatcher.group(2), mMatcher.group(3)); - } - - public Property next() throws ParseException { - return next(false); - } - - public String remaining() { - return mStr.substring(mPos); - } - - public int pos() { - return mPos + mOffset; - } -} diff --git a/src/android/bluetooth/client/pbap/utils/ObexAppParameters.java b/src/android/bluetooth/client/pbap/utils/ObexAppParameters.java deleted file mode 100644 index d70d1e4..0000000 --- a/src/android/bluetooth/client/pbap/utils/ObexAppParameters.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap.utils; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; - -import javax.obex.HeaderSet; - -public final class ObexAppParameters { - - private final HashMap<Byte, byte[]> mParams; - - public ObexAppParameters() { - mParams = new HashMap<Byte, byte[]>(); - } - - public ObexAppParameters(byte[] raw) { - mParams = new HashMap<Byte, byte[]>(); - - if (raw != null) { - for (int i = 0; i < raw.length;) { - if (raw.length - i < 2) { - break; - } - - byte tag = raw[i++]; - byte len = raw[i++]; - - if (raw.length - i - len < 0) { - break; - } - - byte[] val = new byte[len]; - - System.arraycopy(raw, i, val, 0, len); - this.add(tag, val); - - i += len; - } - } - } - - public static ObexAppParameters fromHeaderSet(HeaderSet headerset) { - try { - byte[] raw = (byte[]) headerset.getHeader(HeaderSet.APPLICATION_PARAMETER); - return new ObexAppParameters(raw); - } catch (IOException e) { - // won't happen - } - - return null; - } - - public byte[] getHeader() { - int length = 0; - - for (Map.Entry<Byte, byte[]> entry : mParams.entrySet()) { - length += (entry.getValue().length + 2); - } - - byte[] ret = new byte[length]; - - int idx = 0; - for (Map.Entry<Byte, byte[]> entry : mParams.entrySet()) { - length = entry.getValue().length; - - ret[idx++] = entry.getKey(); - ret[idx++] = (byte) length; - System.arraycopy(entry.getValue(), 0, ret, idx, length); - idx += length; - } - - return ret; - } - - public void addToHeaderSet(HeaderSet headerset) { - if (mParams.size() > 0) { - headerset.setHeader(HeaderSet.APPLICATION_PARAMETER, getHeader()); - } - } - - public boolean exists(byte tag) { - return mParams.containsKey(tag); - } - - public void add(byte tag, byte val) { - byte[] bval = ByteBuffer.allocate(1).put(val).array(); - mParams.put(tag, bval); - } - - public void add(byte tag, short val) { - byte[] bval = ByteBuffer.allocate(2).putShort(val).array(); - mParams.put(tag, bval); - } - - public void add(byte tag, int val) { - byte[] bval = ByteBuffer.allocate(4).putInt(val).array(); - mParams.put(tag, bval); - } - - public void add(byte tag, long val) { - byte[] bval = ByteBuffer.allocate(8).putLong(val).array(); - mParams.put(tag, bval); - } - - public void add(byte tag, String val) { - byte[] bval = val.getBytes(); - mParams.put(tag, bval); - } - - public void add(byte tag, byte[] bval) { - mParams.put(tag, bval); - } - - public byte getByte(byte tag) { - byte[] bval = mParams.get(tag); - - if (bval == null || bval.length < 1) { - return 0; - } - - return ByteBuffer.wrap(bval).get(); - } - - public short getShort(byte tag) { - byte[] bval = mParams.get(tag); - - if (bval == null || bval.length < 2) { - return 0; - } - - return ByteBuffer.wrap(bval).getShort(); - } - - public int getInt(byte tag) { - byte[] bval = mParams.get(tag); - - if (bval == null || bval.length < 4) { - return 0; - } - - return ByteBuffer.wrap(bval).getInt(); - } - - public String getString(byte tag) { - byte[] bval = mParams.get(tag); - - if (bval == null) { - return null; - } - - return new String(bval); - } - - public byte[] getByteArray(byte tag) { - byte[] bval = mParams.get(tag); - - return bval; - } - - @Override - public String toString() { - return mParams.toString(); - } -} diff --git a/src/android/bluetooth/client/pbap/utils/ObexTime.java b/src/android/bluetooth/client/pbap/utils/ObexTime.java deleted file mode 100644 index 74bc2ab..0000000 --- a/src/android/bluetooth/client/pbap/utils/ObexTime.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.client.pbap.utils; - -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public final class ObexTime { - - private Date mDate; - - public ObexTime(String time) { - /* - * match OBEX time string: YYYYMMDDTHHMMSS with optional UTF offset - * +/-hhmm - */ - Pattern p = Pattern - .compile("(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})(([+-])(\\d{2})(\\d{2}))?"); - Matcher m = p.matcher(time); - - if (m.matches()) { - - /* - * matched groups are numberes as follows: YYYY MM DD T HH MM SS + - * hh mm ^^^^ ^^ ^^ ^^ ^^ ^^ ^ ^^ ^^ 1 2 3 4 5 6 8 9 10 all groups - * are guaranteed to be numeric so conversion will always succeed - * (except group 8 which is either + or -) - */ - - Calendar cal = Calendar.getInstance(); - cal.set(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)) - 1, - Integer.parseInt(m.group(3)), Integer.parseInt(m.group(4)), - Integer.parseInt(m.group(5)), Integer.parseInt(m.group(6))); - - /* - * if 7th group is matched then we have UTC offset information - * included - */ - if (m.group(7) != null) { - int ohh = Integer.parseInt(m.group(9)); - int omm = Integer.parseInt(m.group(10)); - - /* time zone offset is specified in miliseconds */ - int offset = (ohh * 60 + omm) * 60 * 1000; - - if (m.group(8).equals("-")) { - offset = -offset; - } - - TimeZone tz = TimeZone.getTimeZone("UTC"); - tz.setRawOffset(offset); - - cal.setTimeZone(tz); - } - - mDate = cal.getTime(); - } - } - - public ObexTime(Date date) { - mDate = date; - } - - public Date getTime() { - return mDate; - } - - @Override - public String toString() { - if (mDate == null) { - return null; - } - - Calendar cal = Calendar.getInstance(); - cal.setTime(mDate); - - /* note that months are numbered stating from 0 */ - return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02d", - cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, - cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY), - cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)); - } -} |