Loading android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java +56 −6 Original line number Diff line number Diff line Loading @@ -17,22 +17,27 @@ package com.android.bluetooth.pbapclient; import android.accounts.Account; import android.util.Log; 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 com.android.vcard.exception.VCardVersionException; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; class BluetoothPbapVcardList { private static final String TAG = BluetoothPbapVcardList.class.getSimpleName(); // {@link BufferedInputStream#DEFAULT_BUFFER_SIZE} is not public private static final int BIS_DEFAULT_BUFFER_SIZE = 8192; private final ArrayList<VCardEntry> mCards = new ArrayList<VCardEntry>(); private final Account mAccount; Loading @@ -53,6 +58,10 @@ class BluetoothPbapVcardList { } BluetoothPbapVcardList(Account account, InputStream in, byte format) throws IOException { if (format != PbapClientConnectionHandler.VCARD_TYPE_21 && format != PbapClientConnectionHandler.VCARD_TYPE_30) { throw new IllegalArgumentException("Unsupported vCard version."); } mAccount = account; parse(in, format); } Loading @@ -68,19 +77,60 @@ class BluetoothPbapVcardList { VCardEntryConstructor constructor = new VCardEntryConstructor(VCardConfig.VCARD_TYPE_V21_GENERIC, mAccount); VCardEntryCounter counter = new VCardEntryCounter(); CardEntryHandler handler = new CardEntryHandler(); CardEntryHandler handler = new CardEntryHandler(); constructor.addEntryHandler(handler); parser.addInterpreter(constructor); parser.addInterpreter(counter); // {@link BufferedInputStream} supports the {@link InputStream#mark} and // {@link InputStream#reset} methods. BufferedInputStream bufferedInput = new BufferedInputStream(in); bufferedInput.mark(BIS_DEFAULT_BUFFER_SIZE /* readlimit */); // If there is a {@link VCardVersionException}, try parsing again with a different // version. Otherwise, parsing either succeeds (i.e., no {@link VCardException}) or it // fails with a different {@link VCardException}. if (parsedWithVcardVersionException(parser, bufferedInput)) { // PBAP v1.2.3 only supports vCard versions 2.1 and 3.0; it's one or the other if (format == PbapClientConnectionHandler.VCARD_TYPE_21) { parser = new VCardParser_V30(); Log.w(TAG, "vCard version and Parser mismatch; expected v2.1, switching to v3.0"); } else { parser = new VCardParser_V21(); Log.w(TAG, "vCard version and Parser mismatch; expected v3.0, switching to v2.1"); } // reset and try again bufferedInput.reset(); mCards.clear(); constructor.clear(); parser.addInterpreter(constructor); if (parsedWithVcardVersionException(parser, bufferedInput)) { Log.e(TAG, "unsupported vCard version, neither v2.1 nor v3.0"); } } } /** * Attempts to parse, with an eye on whether the correct version of Parser is used. * * @param parser -- the {@link VCardParser} to use. * @param in -- the {@link InputStream} to parse. * @return {@code true} if there was a {@link VCardVersionException}; {@code false} if there * is any other {@link VCardException} or succeeds (i.e., no {@link VCardException}). * @throws IOException if there's an issue reading the {@link InputStream}. */ private boolean parsedWithVcardVersionException(VCardParser parser, InputStream in) throws IOException { try { parser.parse(in); } catch (VCardException e) { e.printStackTrace(); } catch (VCardVersionException e1) { Log.w(TAG, "vCard version and Parser mismatch", e1); return true; } catch (VCardException e2) { Log.e(TAG, "vCard exception", e2); } return false; } public int getCount() { Loading android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java +6 −2 Original line number Diff line number Diff line Loading @@ -435,7 +435,9 @@ class PbapClientConnectionHandler extends Handler { Log.w(TAG, "Download contacts incomplete, index exceeded upper limit."); } } catch (IOException e) { Log.w(TAG, "Download contacts failure" + e.toString()); Log.e(TAG, "Download contacts failure", e); } catch (IllegalArgumentException e) { Log.e(TAG, "Download contacts failure: " + e.getMessage(), e); } } Loading @@ -451,7 +453,9 @@ class PbapClientConnectionHandler extends Handler { processor.setResults(request.getList()); processor.onPullComplete(); } catch (IOException e) { Log.w(TAG, "Download call log failure"); Log.e(TAG, "Download call log failure", e); } catch (IllegalArgumentException e) { Log.e(TAG, "Download call log failure: " + e.getMessage(), e); } } Loading android/app/tests/unit/res/raw/unsupported_version.vcf 0 → 100644 +10 −0 Original line number Diff line number Diff line BEGIN:VCARD VERSION:googol FN:Jean Dupont N:Dupont;Jean ADR;WORK;QUOTED-PRINTABLE:;Paris 75010;91 Rue du Faubourg Saint- Martin TEL;CELL;PREF:+1234 56789 EMAIL;INTERNET:jean.dupont@example.com X-BT-UID:A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 END:VCARD android/app/tests/unit/res/raw/v21_simple.vcf 0 → 100644 +10 −0 Original line number Diff line number Diff line BEGIN:VCARD VERSION:2.1 FN:Jean Dupont N:Dupont;Jean ADR;WORK;QUOTED-PRINTABLE:;Paris 75010;91 Rue du Faubourg Saint- Martin TEL;CELL;PREF:+1234 56789 EMAIL;INTERNET:jean.dupont@example.com X-BT-UID:A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 END:VCARD android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookTest.java +18 −2 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ public class BluetoothPbapRequestPullPhoneBookTest { } @Test public void readResponse_failWithMockInputStream() { public void readResponse_failWithInputStreamThatThrowsIOEWhenRead() { final long filter = 1; final byte format = 0; // Will be properly handled as VCARD_TYPE_21. final int maxListCount = 0; // Will be specially handled as 65535. Loading @@ -77,7 +77,23 @@ public class BluetoothPbapRequestPullPhoneBookTest { BluetoothPbapRequestPullPhoneBook request = new BluetoothPbapRequestPullPhoneBook( PB_NAME, ACCOUNT, filter, format, maxListCount, listStartOffset); InputStream is = mock(InputStream.class); final InputStream is = new InputStream() { @Override public int read() throws IOException { throw new IOException(); } @Override public int read(byte[] b) throws IOException { throw new IOException(); } @Override public int read(byte[] b, int off, int len) throws IOException { throw new IOException(); } }; assertThrows(IOException.class, () -> request.readResponse(is)); } Loading Loading
android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java +56 −6 Original line number Diff line number Diff line Loading @@ -17,22 +17,27 @@ package com.android.bluetooth.pbapclient; import android.accounts.Account; import android.util.Log; 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 com.android.vcard.exception.VCardVersionException; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; class BluetoothPbapVcardList { private static final String TAG = BluetoothPbapVcardList.class.getSimpleName(); // {@link BufferedInputStream#DEFAULT_BUFFER_SIZE} is not public private static final int BIS_DEFAULT_BUFFER_SIZE = 8192; private final ArrayList<VCardEntry> mCards = new ArrayList<VCardEntry>(); private final Account mAccount; Loading @@ -53,6 +58,10 @@ class BluetoothPbapVcardList { } BluetoothPbapVcardList(Account account, InputStream in, byte format) throws IOException { if (format != PbapClientConnectionHandler.VCARD_TYPE_21 && format != PbapClientConnectionHandler.VCARD_TYPE_30) { throw new IllegalArgumentException("Unsupported vCard version."); } mAccount = account; parse(in, format); } Loading @@ -68,19 +77,60 @@ class BluetoothPbapVcardList { VCardEntryConstructor constructor = new VCardEntryConstructor(VCardConfig.VCARD_TYPE_V21_GENERIC, mAccount); VCardEntryCounter counter = new VCardEntryCounter(); CardEntryHandler handler = new CardEntryHandler(); CardEntryHandler handler = new CardEntryHandler(); constructor.addEntryHandler(handler); parser.addInterpreter(constructor); parser.addInterpreter(counter); // {@link BufferedInputStream} supports the {@link InputStream#mark} and // {@link InputStream#reset} methods. BufferedInputStream bufferedInput = new BufferedInputStream(in); bufferedInput.mark(BIS_DEFAULT_BUFFER_SIZE /* readlimit */); // If there is a {@link VCardVersionException}, try parsing again with a different // version. Otherwise, parsing either succeeds (i.e., no {@link VCardException}) or it // fails with a different {@link VCardException}. if (parsedWithVcardVersionException(parser, bufferedInput)) { // PBAP v1.2.3 only supports vCard versions 2.1 and 3.0; it's one or the other if (format == PbapClientConnectionHandler.VCARD_TYPE_21) { parser = new VCardParser_V30(); Log.w(TAG, "vCard version and Parser mismatch; expected v2.1, switching to v3.0"); } else { parser = new VCardParser_V21(); Log.w(TAG, "vCard version and Parser mismatch; expected v3.0, switching to v2.1"); } // reset and try again bufferedInput.reset(); mCards.clear(); constructor.clear(); parser.addInterpreter(constructor); if (parsedWithVcardVersionException(parser, bufferedInput)) { Log.e(TAG, "unsupported vCard version, neither v2.1 nor v3.0"); } } } /** * Attempts to parse, with an eye on whether the correct version of Parser is used. * * @param parser -- the {@link VCardParser} to use. * @param in -- the {@link InputStream} to parse. * @return {@code true} if there was a {@link VCardVersionException}; {@code false} if there * is any other {@link VCardException} or succeeds (i.e., no {@link VCardException}). * @throws IOException if there's an issue reading the {@link InputStream}. */ private boolean parsedWithVcardVersionException(VCardParser parser, InputStream in) throws IOException { try { parser.parse(in); } catch (VCardException e) { e.printStackTrace(); } catch (VCardVersionException e1) { Log.w(TAG, "vCard version and Parser mismatch", e1); return true; } catch (VCardException e2) { Log.e(TAG, "vCard exception", e2); } return false; } public int getCount() { Loading
android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java +6 −2 Original line number Diff line number Diff line Loading @@ -435,7 +435,9 @@ class PbapClientConnectionHandler extends Handler { Log.w(TAG, "Download contacts incomplete, index exceeded upper limit."); } } catch (IOException e) { Log.w(TAG, "Download contacts failure" + e.toString()); Log.e(TAG, "Download contacts failure", e); } catch (IllegalArgumentException e) { Log.e(TAG, "Download contacts failure: " + e.getMessage(), e); } } Loading @@ -451,7 +453,9 @@ class PbapClientConnectionHandler extends Handler { processor.setResults(request.getList()); processor.onPullComplete(); } catch (IOException e) { Log.w(TAG, "Download call log failure"); Log.e(TAG, "Download call log failure", e); } catch (IllegalArgumentException e) { Log.e(TAG, "Download call log failure: " + e.getMessage(), e); } } Loading
android/app/tests/unit/res/raw/unsupported_version.vcf 0 → 100644 +10 −0 Original line number Diff line number Diff line BEGIN:VCARD VERSION:googol FN:Jean Dupont N:Dupont;Jean ADR;WORK;QUOTED-PRINTABLE:;Paris 75010;91 Rue du Faubourg Saint- Martin TEL;CELL;PREF:+1234 56789 EMAIL;INTERNET:jean.dupont@example.com X-BT-UID:A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 END:VCARD
android/app/tests/unit/res/raw/v21_simple.vcf 0 → 100644 +10 −0 Original line number Diff line number Diff line BEGIN:VCARD VERSION:2.1 FN:Jean Dupont N:Dupont;Jean ADR;WORK;QUOTED-PRINTABLE:;Paris 75010;91 Rue du Faubourg Saint- Martin TEL;CELL;PREF:+1234 56789 EMAIL;INTERNET:jean.dupont@example.com X-BT-UID:A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 END:VCARD
android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookTest.java +18 −2 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ public class BluetoothPbapRequestPullPhoneBookTest { } @Test public void readResponse_failWithMockInputStream() { public void readResponse_failWithInputStreamThatThrowsIOEWhenRead() { final long filter = 1; final byte format = 0; // Will be properly handled as VCARD_TYPE_21. final int maxListCount = 0; // Will be specially handled as 65535. Loading @@ -77,7 +77,23 @@ public class BluetoothPbapRequestPullPhoneBookTest { BluetoothPbapRequestPullPhoneBook request = new BluetoothPbapRequestPullPhoneBook( PB_NAME, ACCOUNT, filter, format, maxListCount, listStartOffset); InputStream is = mock(InputStream.class); final InputStream is = new InputStream() { @Override public int read() throws IOException { throw new IOException(); } @Override public int read(byte[] b) throws IOException { throw new IOException(); } @Override public int read(byte[] b, int off, int len) throws IOException { throw new IOException(); } }; assertThrows(IOException.class, () -> request.readResponse(is)); } Loading