PBAP OBEX session uses Handler/HandlerThread now.
am: a3acb17ad3
* commit 'a3acb17ad38d82048816b37cc1eb6b7872540961':
PBAP OBEX session uses Handler/HandlerThread now.
diff --git a/src/android/bluetooth/client/map/BluetoothMapBmessage.java b/src/android/bluetooth/client/map/BluetoothMapBmessage.java
index 84e4c75..e06b033 100644
--- a/src/android/bluetooth/client/map/BluetoothMapBmessage.java
+++ b/src/android/bluetooth/client/map/BluetoothMapBmessage.java
@@ -159,6 +159,7 @@
json.put("status", mBmsgStatus);
json.put("type", mBmsgType);
json.put("folder", mBmsgFolder);
+ json.put("charset", mBbodyCharset);
json.put("message", mMessage);
} catch (JSONException e) {
// do nothing
diff --git a/src/android/bluetooth/client/map/BluetoothMapBmessageParser.java b/src/android/bluetooth/client/map/BluetoothMapBmessageParser.java
index ef75e7b..5c89e4d 100644
--- a/src/android/bluetooth/client/map/BluetoothMapBmessageParser.java
+++ b/src/android/bluetooth/client/map/BluetoothMapBmessageParser.java
@@ -33,11 +33,13 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.text.ParseException;
class BluetoothMapBmessageParser {
private final static String TAG = "BluetoothMapBmessageParser";
+ private final static boolean DBG = false;
private final static String CRLF = "\r\n";
@@ -75,6 +77,10 @@
static public BluetoothMapBmessage createBmessage(String str) {
BluetoothMapBmessageParser p = new BluetoothMapBmessageParser();
+ if (DBG) {
+ Log.d(TAG, "actual wired contents: " + str);
+ }
+
try {
p.parse(str);
} catch (IOException e) {
@@ -291,6 +297,17 @@
} while (!prop.equals(BEGIN_MSG));
/*
+ * check that the charset is always set to UTF-8. We expect only text transfer (in lieu with
+ * the MAPv12 specifying only RFC2822 (text only) for MMS/EMAIL and SMS do not support
+ * non-text content. If the charset is not set to UTF-8, it is safe to set the message as
+ * empty. We force the getMessage (see BluetoothMasClient) to only call getMessage with
+ * UTF-8 as the MCE is not obliged to support native charset.
+ */
+ if (!mBmsg.mBbodyCharset.equals("UTF-8")) {
+ Log.e(TAG, "The charset was not set to charset UTF-8: " + mBmsg.mBbodyCharset);
+ }
+
+ /*
* <bmessage-body-content>::={ "BEGIN:MSG"<CRLF> 'message'<CRLF>
* "END:MSG"<CRLF> }
*/
@@ -314,7 +331,11 @@
if (prop != null) {
if (prop.equals(END_MSG)) {
- mBmsg.mMessage = new String(data, 0, messageLen);
+ if (mBmsg.mBbodyCharset.equals("UTF-8")) {
+ mBmsg.mMessage = new String(data, 0, messageLen, StandardCharsets.UTF_8);
+ } else {
+ mBmsg.mMessage = null;
+ }
} else {
/* Handle possible exception for incorrect LENGTH value
* from MSE while parsing GET Message response */
@@ -346,7 +367,11 @@
throw expected(END_MSG);
}
- mBmsg.mMessage = remng.substring(0, messageLen);
+ if (mBmsg.mBbodyCharset.equals("UTF-8")) {
+ mBmsg.mMessage = remng.substring(0, messageLen);
+ } else {
+ mBmsg.mMessage = null;
+ }
}
prop = mParser.next();
diff --git a/src/android/bluetooth/client/map/BluetoothMasClient.java b/src/android/bluetooth/client/map/BluetoothMasClient.java
index 7f71693..87f5a38 100644
--- a/src/android/bluetooth/client/map/BluetoothMasClient.java
+++ b/src/android/bluetooth/client/map/BluetoothMasClient.java
@@ -962,7 +962,7 @@
* @return <code>true</code> if request has been sent, <code>false</code>
* otherwise
*/
- public boolean getMessage(String handle, CharsetType charset, boolean attachment) {
+ public boolean getMessage(String handle, boolean attachment) {
if (mObexSession == null) {
return false;
}
@@ -974,8 +974,10 @@
return false;
}
- BluetoothMasRequest request = new BluetoothMasRequestGetMessage(handle, charset,
- attachment);
+ // Since we support only text messaging via Bluetooth, it is OK to restrict the requests to
+ // force conversion to UTF-8.
+ BluetoothMasRequest request =
+ new BluetoothMasRequestGetMessage(handle, CharsetType.UTF_8, attachment);
return mObexSession.makeRequest(request);
}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java
index b50fd0f..923bff0 100644
--- a/src/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java
@@ -25,6 +25,8 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import javax.obex.ClientSession;
import javax.obex.HeaderSet;
@@ -69,7 +71,17 @@
Log.e(TAG, "I/O exception while reading response", e);
}
- String bmsg = baos.toString();
+ // Convert the input stream using UTF-8 since the attributes in the payload are all encoded
+ // according to it. The actual message body may need to be transcoded depending on
+ // charset/encoding defined for body-content.
+ String bmsg;
+ try {
+ bmsg = baos.toString(StandardCharsets.UTF_8.name());
+ } catch (UnsupportedEncodingException ex) {
+ Log.e(TAG,
+ "Coudn't decode the bmessage with UTF-8. Something must be really messed up.");
+ return;
+ }
mBmessage = BluetoothMapBmessageParser.createBmessage(bmsg);
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapClient.java b/src/android/bluetooth/client/pbap/BluetoothPbapClient.java
index 5e212e8..b1fc441 100644
--- a/src/android/bluetooth/client/pbap/BluetoothPbapClient.java
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapClient.java
@@ -16,6 +16,7 @@
package android.bluetooth.client.pbap;
+import android.accounts.Account;
import android.bluetooth.BluetoothDevice;
import android.os.Handler;
import android.os.Message;
@@ -72,6 +73,8 @@
* connection and disconnection happens automatically internally.
*/
public class BluetoothPbapClient {
+ private static final boolean DBG = true;
+
private static final String TAG = "BluetoothPbapClient";
/**
@@ -372,6 +375,7 @@
DISCONNECTED, CONNECTING, CONNECTED, DISCONNECTING;
}
+ private final Account mAccount;
private final Handler mClientHandler;
private final BluetoothPbapSession mSession;
private ConnectionState mConnectionState = ConnectionState.DISCONNECTED;
@@ -503,14 +507,20 @@
*
* @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, Handler handler) {
- if (device == null) {
- throw new NullPointerException("BluetothDevice is null");
+ 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;
@@ -696,8 +706,8 @@
*/
public boolean pullPhoneBook(String pbName, long filter, byte format, int maxListCount,
int listStartOffset) {
- BluetoothPbapRequest req = new BluetoothPbapRequestPullPhoneBook(pbName, filter, format,
- maxListCount, listStartOffset);
+ BluetoothPbapRequest req = new BluetoothPbapRequestPullPhoneBook(
+ pbName, mAccount, filter, format, maxListCount, listStartOffset);
return mSession.makeRequest(req);
}
@@ -835,7 +845,8 @@
* @link #EVENT_PULL_VCARD_ERROR} in case of failure
*/
public boolean pullVcardEntry(String handle, long filter, byte format) {
- BluetoothPbapRequest req = new BluetoothPbapRequestPullVcardEntry(handle, filter, format);
+ BluetoothPbapRequest req =
+ new BluetoothPbapRequestPullVcardEntry(handle, mAccount, filter, format);
return mSession.makeRequest(req);
}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java
index 15954b1..411a8de 100644
--- a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java
@@ -16,6 +16,7 @@
package android.bluetooth.client.pbap;
+import android.accounts.Account;
import android.util.Log;
import com.android.vcard.VCardEntry;
@@ -29,19 +30,24 @@
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, long filter, byte format,
+ 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]");
}
@@ -91,12 +97,15 @@
protected void readResponse(InputStream stream) throws IOException {
Log.v(TAG, "readResponse");
- mResponse = new BluetoothPbapVcardList(stream, mFormat);
+ mResponse = new BluetoothPbapVcardList(mAccount, stream, mFormat);
+ if (DBG) {
+ Log.d(TAG, "Read " + mResponse.getCount() + " entries.");
+ }
}
@Override
protected void readResponseHeaders(HeaderSet headerset) {
- Log.v(TAG, "readResponse");
+ Log.v(TAG, "readResponseHeaders");
ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java
index 42b6692..ed823d5 100644
--- a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java
@@ -16,6 +16,7 @@
package android.bluetooth.client.pbap;
+import android.accounts.Account;
import android.util.Log;
import com.android.vcard.VCardEntry;
@@ -35,9 +36,14 @@
private BluetoothPbapVcardList mResponse;
+ private final Account mAccount;
+
private final byte mFormat;
- public BluetoothPbapRequestPullVcardEntry(String handle, long filter, byte format) {
+ public BluetoothPbapRequestPullVcardEntry(
+ String handle, Account account, long filter, byte format) {
+ mAccount = account;
+
mHeaderSet.setHeader(HeaderSet.NAME, handle);
mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
@@ -64,7 +70,7 @@
protected void readResponse(InputStream stream) throws IOException {
Log.v(TAG, "readResponse");
- mResponse = new BluetoothPbapVcardList(stream, mFormat);
+ mResponse = new BluetoothPbapVcardList(mAccount, stream, mFormat);
}
@Override
protected void checkResponseCode(int responseCode) throws IOException {
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java b/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java
index 8e23e1a..6bc75de 100644
--- a/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java
@@ -16,6 +16,9 @@
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;
@@ -32,6 +35,7 @@
class BluetoothPbapVcardList {
private final ArrayList<VCardEntry> mCards = new ArrayList<VCardEntry>();
+ private final Account mAccount;
class CardEntryHandler implements VCardEntryHandler {
@Override
@@ -48,7 +52,8 @@
}
}
- public BluetoothPbapVcardList(InputStream in, byte format) throws IOException {
+ public BluetoothPbapVcardList(Account account, InputStream in, byte format) throws IOException {
+ mAccount = account;
parse(in, format);
}
@@ -61,7 +66,8 @@
parser = new VCardParser_V21();
}
- VCardEntryConstructor constructor = new VCardEntryConstructor();
+ VCardEntryConstructor constructor =
+ new VCardEntryConstructor(VCardConfig.VCARD_TYPE_V21_GENERIC, mAccount);
VCardEntryCounter counter = new VCardEntryCounter();
CardEntryHandler handler = new CardEntryHandler();