DO NOT MERGE Fix SMS delivered successfully but stuck SENDING issue am: abb54d6d36 am: 6e9165b908 -s ours am: 44c3652b4c am: 5a1ae16f4e am: d59eb61a3e -s ours
am: d6e1fa7c20
* commit 'd6e1fa7c20fbddbf9ea5fa7b042bfdf276c1463a':
DO NOT MERGE Fix SMS delivered successfully but stuck SENDING issue
diff --git a/Android.mk b/Android.mk
index e03acdc..7b724d0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -22,7 +22,7 @@
LOCAL_JNI_SHARED_LIBRARIES := libbluetooth_jni
LOCAL_JAVA_LIBRARIES := javax.obex telephony-common libprotobuf-java-micro
-LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard bluetooth.mapsapi sap-api-java-static
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard bluetooth.mapsapi sap-api-java-static android-support-v4
LOCAL_REQUIRED_MODULES := bluetooth.default
LOCAL_MULTILIB := 32
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 85910aa..3652fd3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -27,6 +27,7 @@
<uses-permission android:name="android.permission.BLUETOOTH_MAP" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- WRITE_CONTACTS is used for test cases only -->
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
@@ -80,6 +81,14 @@
android:pathPrefix="/btopp"
android:permission="android.permission.ACCESS_BLUETOOTH_SHARE" />
</provider>
+ <provider android:name="android.support.v4.content.FileProvider"
+ android:authorities="com.google.android.bluetooth.fileprovider"
+ android:grantUriPermissions="true"
+ android:exported="false">
+ <meta-data
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/file_paths" />
+ </provider>
<service
android:process="@string/process"
android:name = ".btservice.AdapterService">
diff --git a/res/values-fa/test_strings.xml b/res/values-fa/test_strings.xml
index 000f3f7..0db14ba 100644
--- a/res/values-fa/test_strings.xml
+++ b/res/values-fa/test_strings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hello" msgid="1740533743008967039">"سلام بر دنیا، تست فعالیت"</string>
+ <string name="hello" msgid="1740533743008967039">"سلام به همه، تست فعالیت"</string>
<string name="app_name" msgid="1203877025577761792">"اشتراک بلوتوث"</string>
<string name="insert_record" msgid="1450997173838378132">"درج سابقه"</string>
<string name="update_record" msgid="2480425402384910635">"تأیید سابقه"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index ed657c0..45d784b 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -24,9 +24,9 @@
<string name="unknown_device" msgid="9221903979877041009">"Onbekend apparaat"</string>
<string name="unknownNumber" msgid="4994750948072751566">"Onbekend"</string>
<string name="airplane_error_title" msgid="2683839635115739939">"Vliegtuigmodus"</string>
- <string name="airplane_error_msg" msgid="8698965595254137230">"U kunt Bluetooth niet gebruiken in Vliegtuigmodus."</string>
+ <string name="airplane_error_msg" msgid="8698965595254137230">"Je kunt Bluetooth niet gebruiken in Vliegtuigmodus."</string>
<string name="bt_enable_title" msgid="8657832550503456572"></string>
- <string name="bt_enable_line1" msgid="7203551583048149">"Als u Bluetooth-services wilt gebruiken, moet u eerst Bluetooth inschakelen."</string>
+ <string name="bt_enable_line1" msgid="7203551583048149">"Als je Bluetooth-services wilt gebruiken, moet je eerst Bluetooth inschakelen."</string>
<string name="bt_enable_line2" msgid="4341936569415937994">"Bluetooth nu inschakelen?"</string>
<string name="bt_enable_cancel" msgid="1988832367505151727">"Annuleren"</string>
<string name="bt_enable_ok" msgid="3432462749994538265">"Inschakelen"</string>
@@ -37,8 +37,8 @@
<string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
<string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"Er is een time-out opgetreden bij het accepteren van een inkomend bestand van \'<xliff:g id="SENDER">%1$s</xliff:g>\'"</string>
<string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Delen via Bluetooth: inkomend bestand"</string>
- <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Wilt u dit bestand ontvangen?"</string>
- <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Er is een inkomend bestand van een ander apparaat beschikbaar. Bevestig dat u dit bestand wilt ontvangen."</string>
+ <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Wilt je dit bestand ontvangen?"</string>
+ <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Er is een inkomend bestand van een ander apparaat beschikbaar. Bevestig dat je dit bestand wilt ontvangen."</string>
<string name="notification_receiving" msgid="4674648179652543984">"Delen via Bluetooth: <xliff:g id="FILE">%1$s</xliff:g> ontvangen"</string>
<string name="notification_received" msgid="3324588019186687985">"Delen via Bluetooth: <xliff:g id="FILE">%1$s</xliff:g> ontvangen"</string>
<string name="notification_received_fail" msgid="3619350997285714746">"Delen via Bluetooth: bestand <xliff:g id="FILE">%1$s</xliff:g> niet ontvangen"</string>
@@ -79,7 +79,7 @@
<string name="not_exist_file_desc" msgid="4059531573790529229">"Het bestand bestaat niet. \n"</string>
<string name="enabling_progress_title" msgid="436157952334723406">"Een ogenblik geduld..."</string>
<string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth inschakelen…"</string>
- <string name="bt_toast_1" msgid="972182708034353383">"Het bestand wordt ontvangen. U kunt de voortgang controleren in het venster \'Meldingen\'."</string>
+ <string name="bt_toast_1" msgid="972182708034353383">"Het bestand wordt ontvangen. Je kunt de voortgang controleren in het venster \'Meldingen\'."</string>
<string name="bt_toast_2" msgid="8602553334099066582">"Het bestand kan niet worden opgehaald."</string>
<string name="bt_toast_3" msgid="6707884165086862518">"Ontvangen van bestand van \'<xliff:g id="SENDER">%1$s</xliff:g>\' is beëindigd"</string>
<string name="bt_toast_4" msgid="4678812947604395649">"Bestand verzenden naar \'<xliff:g id="RECIPIENT">%1$s</xliff:g>\'"</string>
@@ -124,7 +124,7 @@
<string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Wissen"</string>
<string name="bluetooth_map_settings_save" msgid="7635491847388074606">"Opslaan"</string>
<string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"Annuleren"</string>
- <string name="bluetooth_map_settings_intro" msgid="6793938602201480648">"Selecteer de accounts die u wilt delen via Bluetooth. U moet nog steeds elke toegang tot de accounts accepteren wanneer er verbinding wordt gemaakt."</string>
+ <string name="bluetooth_map_settings_intro" msgid="6793938602201480648">"Selecteer de accounts die je wilt delen via Bluetooth. Je moet nog steeds elke toegang tot de accounts accepteren wanneer er verbinding wordt gemaakt."</string>
<string name="bluetooth_map_settings_count" msgid="4557473074937024833">"Plaatsen over:"</string>
<string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"App-pictogram"</string>
<string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Instellingen voor delen van berichten via Bluetooth"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 8fa4161..3b3238b 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -19,17 +19,17 @@
<string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Accesaţi managerul de descărcare."</string>
<string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Permite aplicațiilor să acceseze managerul Distribuire prin Bluetooth și să-l utilizeze la transferul fișierelor."</string>
<string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Acces la dispozitivele Bluetooth din lista albă."</string>
- <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Permite aplicației să treacă temporar pe lista albă un dispozitiv Bluetooth, permiţându-i să trimită fişiere la acest dispozitiv fără confirmare din partea utilizatorului."</string>
+ <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Permite aplicației să treacă temporar pe lista albă un dispozitiv Bluetooth, permițându-i să trimită fişiere la acest dispozitiv fără confirmare din partea utilizatorului."</string>
<string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
<string name="unknown_device" msgid="9221903979877041009">"Dispozitiv necunoscut"</string>
<string name="unknownNumber" msgid="4994750948072751566">"Necunoscut"</string>
<string name="airplane_error_title" msgid="2683839635115739939">"Mod Avion"</string>
<string name="airplane_error_msg" msgid="8698965595254137230">"Nu puteţi utiliza Bluetooth în modul Avion."</string>
<string name="bt_enable_title" msgid="8657832550503456572"></string>
- <string name="bt_enable_line1" msgid="7203551583048149">"Pentru a putea utiliza serviciile Bluetooth, trebuie mai întâi să le activaţi."</string>
- <string name="bt_enable_line2" msgid="4341936569415937994">"Activaţi acum Bluetooth?"</string>
+ <string name="bt_enable_line1" msgid="7203551583048149">"Pentru a putea utiliza serviciile Bluetooth, trebuie mai întâi să le activați."</string>
+ <string name="bt_enable_line2" msgid="4341936569415937994">"Activați acum Bluetooth?"</string>
<string name="bt_enable_cancel" msgid="1988832367505151727">"Anulați"</string>
- <string name="bt_enable_ok" msgid="3432462749994538265">"Activaţi"</string>
+ <string name="bt_enable_ok" msgid="3432462749994538265">"Activați"</string>
<string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transfer de fişier"</string>
<string name="incoming_file_confirm_content" msgid="2752605552743148036">"Acceptați fișierul primit?"</string>
<string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Refuzaţi"</string>
@@ -52,7 +52,7 @@
<string name="download_line3" msgid="4384821622908676061">"Dimensiunea fişierului: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="download_line4" msgid="8535996869722666525"></string>
<string name="download_line5" msgid="3069560415845295386">"Se primeşte fişierul..."</string>
- <string name="download_cancel" msgid="9177305996747500768">"Opriţi"</string>
+ <string name="download_cancel" msgid="9177305996747500768">"Opriți"</string>
<string name="download_ok" msgid="5000360731674466039">"Ascundeţi"</string>
<string name="incoming_line1" msgid="2127419875681087545">"De la"</string>
<string name="incoming_line2" msgid="3348994249285315873">"Numele fișierului"</string>
@@ -70,7 +70,7 @@
<string name="upload_succ_ok" msgid="7705428476405478828">"OK"</string>
<string name="upload_fail_line1" msgid="7899394672421491701">"Fişierul nu a fost trimis la „<xliff:g id="RECIPIENT">%1$s</xliff:g>”."</string>
<string name="upload_fail_line1_2" msgid="2108129204050841798">"Fişier: <xliff:g id="FILE">%1$s</xliff:g>"</string>
- <string name="upload_fail_ok" msgid="5807702461606714296">"Încercaţi din nou"</string>
+ <string name="upload_fail_ok" msgid="5807702461606714296">"Încercați din nou"</string>
<string name="upload_fail_cancel" msgid="9118496285835687125">"Închideţi"</string>
<string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
<string name="unknown_file" msgid="6092727753965095366">"Fişier necunoscut"</string>
@@ -88,7 +88,7 @@
<string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"Nu există spaţiu suficient pe stocarea USB pentru a salva fişierul de la „<xliff:g id="SENDER">%1$s</xliff:g>”"</string>
<string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"Nu există suficient spaţiu pe cardul SD pentru a salva fişierul de la „<xliff:g id="SENDER">%1$s</xliff:g>”"</string>
<string name="bt_sm_2_2" msgid="2965243265852680543">"Spaţiu necesar: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
- <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Există prea multe solicitări în curs de procesare. Încercaţi din nou mai târziu."</string>
+ <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Există prea multe solicitări în curs de procesare. Încercați din nou mai târziu."</string>
<string name="status_pending" msgid="2503691772030877944">"Transferul fişierului nu a început încă."</string>
<string name="status_running" msgid="6562808920311008696">"Transferul fişierului este în curs de desfăşurare."</string>
<string name="status_success" msgid="239573225847565868">"Transferul fişierului s-a încheiat."</string>
diff --git a/res/xml/file_paths.xml b/res/xml/file_paths.xml
new file mode 100644
index 0000000..72d848d
--- /dev/null
+++ b/res/xml/file_paths.xml
@@ -0,0 +1,3 @@
+<paths xmlns:android="https://schemas.android.com/apk/res/android">
+ <external-path name="bluetooth" path="/" />
+</paths>
diff --git a/src/com/android/bluetooth/Utils.java b/src/com/android/bluetooth/Utils.java
index a16d3b9..6a467f9 100644
--- a/src/com/android/bluetooth/Utils.java
+++ b/src/com/android/bluetooth/Utils.java
@@ -288,14 +288,7 @@
return true;
}
// Enforce location permission for apps targeting M and later versions
- boolean enforceLocationPermission = true;
- try {
- enforceLocationPermission = context.getPackageManager().getApplicationInfo(
- callingPackage, 0).targetSdkVersion >= Build.VERSION_CODES.M;
- } catch (PackageManager.NameNotFoundException e) {
- // In case of exception, enforce permission anyway
- }
- if (enforceLocationPermission) {
+ if (isMApp(context, callingPackage)) {
throw new SecurityException("Need ACCESS_COARSE_LOCATION or "
+ "ACCESS_FINE_LOCATION permission to get scan results");
} else {
@@ -317,6 +310,20 @@
android.Manifest.permission.PEERS_MAC_ADDRESS) == PackageManager.PERMISSION_GRANTED;
}
+ public static boolean isLegacyForegroundApp(Context context, String pkgName) {
+ return !isMApp(context, pkgName) && isForegroundApp(context, pkgName);
+ }
+
+ private static boolean isMApp(Context context, String pkgName) {
+ try {
+ return context.getPackageManager().getApplicationInfo(pkgName, 0)
+ .targetSdkVersion >= Build.VERSION_CODES.M;
+ } catch (PackageManager.NameNotFoundException e) {
+ // In case of exception, assume M app
+ }
+ return true;
+ }
+
/**
* Return true if the specified package name is a foreground app.
*
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index a04d5a3..26ef18d 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -641,12 +641,13 @@
private boolean hasScanResultPermission(final ScanClient client) {
final boolean requiresLocationEnabled =
getResources().getBoolean(R.bool.strict_location_check);
- final boolean locationEnabled = Settings.Secure.getInt(getContentResolver(),
+ final boolean locationEnabledSetting = Settings.Secure.getInt(getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF)
!= Settings.Secure.LOCATION_MODE_OFF;
-
- return (client.hasPeersMacAddressPermission ||
- (client.hasLocationPermission && (!requiresLocationEnabled || locationEnabled)));
+ final boolean locationEnabled = !requiresLocationEnabled || locationEnabledSetting
+ || client.legacyForegroundApp;
+ return (client.hasPeersMacAddressPermission
+ || (client.hasLocationPermission && locationEnabled));
}
// Check if a scan record matches a specific filters.
@@ -1378,12 +1379,12 @@
if (needsPrivilegedPermissionForScan(settings)) {
enforcePrivilegedPermission();
}
- boolean hasLocationPermission = Utils.checkCallerHasLocationPermission(this,
- mAppOps, callingPackage);
final ScanClient scanClient = new ScanClient(appIf, isServer, settings, filters, storages);
- scanClient.hasLocationPermission = hasLocationPermission;
+ scanClient.hasLocationPermission = Utils.checkCallerHasLocationPermission(this, mAppOps,
+ callingPackage);
scanClient.hasPeersMacAddressPermission = Utils.checkCallerHasPeersMacAddressPermission(
this);
+ scanClient.legacyForegroundApp = Utils.isLegacyForegroundApp(this, callingPackage);
mScanManager.startScan(scanClient);
}
diff --git a/src/com/android/bluetooth/gatt/ScanClient.java b/src/com/android/bluetooth/gatt/ScanClient.java
index d42df39..64d3e1f 100644
--- a/src/com/android/bluetooth/gatt/ScanClient.java
+++ b/src/com/android/bluetooth/gatt/ScanClient.java
@@ -40,6 +40,8 @@
boolean appDied;
boolean hasLocationPermission;
boolean hasPeersMacAddressPermission;
+ // Pre-M apps are allowed to get scan results even if location is disabled
+ boolean legacyForegroundApp;
private static final ScanSettings DEFAULT_SCAN_SETTINGS = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index d226e7c..0cf5f33 100644
--- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -2763,6 +2763,11 @@
} else {
Log.e(TAG,"processNoiceReductionEvent: AudioParamNrec is null ");
}
+
+ if (mActiveScoDevice != null && mActiveScoDevice.equals(device)
+ && mAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
+ setAudioParameters(device);
+ }
}
// 2 - WBS on
diff --git a/src/com/android/bluetooth/map/BluetoothMapContent.java b/src/com/android/bluetooth/map/BluetoothMapContent.java
index 28f5d42..7ced91b 100644
--- a/src/com/android/bluetooth/map/BluetoothMapContent.java
+++ b/src/com/android/bluetooth/map/BluetoothMapContent.java
@@ -117,7 +117,7 @@
// MAP specification states that the default value for parameter mask are
// the #REQUIRED attributes in the DTD, and not all enabled
public static final long PARAMETER_MASK_ALL_ENABLED = 0xFFFFFFFFL;
- public static final long PARAMETER_MASK_DEFAULT = 0x5E3L;
+ public static final long PARAMETER_MASK_DEFAULT = 0x5EBL;
public static final long CONVO_PARAMETER_MASK_ALL_ENABLED = 0xFFFFFFFFL;
public static final long CONVO_PARAMETER_MASK_DEFAULT =
CONVO_PARAM_MASK_CONVO_NAME |
diff --git a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
index 417be25..9aae8cf 100644
--- a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
+++ b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
@@ -3040,6 +3040,9 @@
if(status != 0/*0 is success*/) {
msgInfo.statusDelivered = status;
if(D) Log.d(TAG, "msgInfo.statusDelivered = " + status);
+ Sms.moveMessageToFolder(mContext, msgInfo.uri, Sms.MESSAGE_TYPE_FAILED, 0);
+ } else {
+ Sms.moveMessageToFolder(mContext, msgInfo.uri, Sms.MESSAGE_TYPE_SENT, 0);
}
}
if (msgInfo.partsDelivered == msgInfo.parts) {
diff --git a/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/src/com/android/bluetooth/opp/BluetoothOppUtility.java
index ea465f4..58f4677 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppUtility.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppUtility.java
@@ -54,6 +54,7 @@
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
+import android.support.v4.content.FileProvider;
/**
* This class has some utilities for Opp application;
*/
@@ -186,7 +187,8 @@
return;
}
- Uri path = Uri.parse(fileName);
+ Uri path = FileProvider.getUriForFile(context,
+ "com.google.android.bluetooth.fileprovider", f);
// If there is no scheme, then it must be a file
if (path.getScheme() == null) {
path = Uri.fromFile(new File(fileName));
@@ -196,7 +198,22 @@
Intent activityIntent = new Intent(Intent.ACTION_VIEW);
activityIntent.setDataAndTypeAndNormalize(path, mimetype);
+ List<ResolveInfo> resInfoList = context.getPackageManager()
+ .queryIntentActivities(activityIntent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+
+ // Grant permissions for any app that can handle a file to access it
+ for (ResolveInfo resolveInfo : resInfoList) {
+ String packageName = resolveInfo.activityInfo.packageName;
+ context.grantUriPermission(packageName, path,
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
+ Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ }
+
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ activityIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ activityIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+
try {
if (V) Log.d(TAG, "ACTION_VIEW intent sent out: " + path + " / " + mimetype);
context.startActivity(activityIntent);
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java b/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
index de8275e..748e7a5 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
@@ -623,7 +623,6 @@
HandlerForStringBuffer buffer = null;
try {
- VCardFilter vcardfilter = new VCardFilter(ignorefilter ? null : filter);
composer = new BluetoothPbapCallLogComposer(mContext);
buffer = new HandlerForStringBuffer(op, ownerVCard);
if (!composer.init(CallLog.Calls.CONTENT_URI, selection, null, CALLLOG_SORT_ORDER)
@@ -638,9 +637,6 @@
break;
}
String vcard = composer.createOneEntry(vcardType21);
- if (vcard != null) {
- vcard = vcardfilter.apply(vcard, vcardType21);
- }
if (vcard == null) {
Log.e(TAG,
"Failed to read a contact. Error reason: " + composer.getErrorReason());
diff --git a/src/com/android/bluetooth/sap/SapMessage.java b/src/com/android/bluetooth/sap/SapMessage.java
index 848745d..e836fba 100644
--- a/src/com/android/bluetooth/sap/SapMessage.java
+++ b/src/com/android/bluetooth/sap/SapMessage.java
@@ -28,7 +28,7 @@
public static final String TAG = "SapMessage";
public static final boolean DEBUG = SapService.DEBUG;
public static final boolean VERBOSE = SapService.VERBOSE;
- public static final boolean TEST = SapService.PTS_TEST;
+ public static final boolean TEST = false;
/* Message IDs - SAP specification */
public static final int ID_CONNECT_REQ = 0x00;
@@ -404,10 +404,8 @@
case ID_DISCONNECT_REQ: /* No params */
break;
default:
- if(TEST == false) {
- Log.e(TAG, "Unknown request type");
- return null;
- }
+ Log.e(TAG, "Unknown request type");
+ return null;
}
return newMessage;
}
@@ -456,18 +454,25 @@
int paramId;
int paramLength;
boolean success = true;
+ int skipLen = 0;
+
for(int i = 0; i < count; i++) {
paramId = is.read();
is.read(); // Skip the reserved byte
paramLength = is.read();
paramLength = paramLength << 8 | is.read();
+
+ // As per SAP spec padding should be 0-3 bytes
+ if ((paramLength % 4) != 0)
+ skipLen = 4 - (paramLength % 4);
+
if(VERBOSE) Log.i(TAG, "parsing paramId: " + paramId + " with length: " + paramLength);
switch(paramId) {
case PARAM_MAX_MSG_SIZE_ID:
if(paramLength != PARAM_MAX_MSG_SIZE_LENGTH) {
Log.e(TAG, "Received PARAM_MAX_MSG_SIZE with wrong length: " +
paramLength + " skipping this parameter.");
- skip(is, paramLength + (4 - (paramLength % 4)));
+ skip(is, paramLength + skipLen);
success = false;
} else {
mMaxMsgSize = is.read();
@@ -478,18 +483,18 @@
case PARAM_COMMAND_APDU_ID:
mApdu = new byte[paramLength];
read(is, mApdu);
- skip(is, 4 - (paramLength % 4));
+ skip(is, skipLen);
break;
case PARAM_COMMAND_APDU7816_ID:
mApdu7816 = new byte[paramLength];
read(is, mApdu7816);
- skip(is, 4 - (paramLength % 4));
+ skip(is, skipLen);
break;
case PARAM_TRANSPORT_PROTOCOL_ID:
if(paramLength != PARAM_TRANSPORT_PROTOCOL_LENGTH) {
Log.e(TAG, "Received PARAM_TRANSPORT_PROTOCOL with wrong length: " +
paramLength + " skipping this parameter.");
- skip(is, paramLength + (4 - (paramLength % 4)));
+ skip(is, paramLength + skipLen);
success = false;
} else {
mTransportProtocol = is.read();
@@ -497,95 +502,81 @@
}
break;
case PARAM_CONNECTION_STATUS_ID:
- // not needed - server -> client
- if(TEST) {
- if(paramLength != PARAM_CONNECTION_STATUS_LENGTH) {
- Log.e(TAG, "Received PARAM_CONNECTION_STATUS with wrong length: " +
- paramLength + " skipping this parameter.");
- skip(is, paramLength + (4 - (paramLength % 4)));
- success = false;
- } else {
- mConnectionStatus = is.read();
- skip(is, 4 - PARAM_CONNECTION_STATUS_LENGTH);
- }
- break;
- } // Fall through if TEST == false
+ // not needed for server role, but used for module test
+ if(paramLength != PARAM_CONNECTION_STATUS_LENGTH) {
+ Log.e(TAG, "Received PARAM_CONNECTION_STATUS with wrong length: " +
+ paramLength + " skipping this parameter.");
+ skip(is, paramLength + skipLen);
+ success = false;
+ } else {
+ mConnectionStatus = is.read();
+ skip(is, 4 - PARAM_CONNECTION_STATUS_LENGTH);
+ }
+ break;
case PARAM_CARD_READER_STATUS_ID:
- // not needed - server -> client
- if(TEST) {
- if(paramLength != PARAM_CARD_READER_STATUS_LENGTH) {
- Log.e(TAG, "Received PARAM_CARD_READER_STATUS with wrong length: " +
- paramLength + " skipping this parameter.");
- skip(is, paramLength + (4 - (paramLength % 4)));
- success = false;
- } else {
- mCardReaderStatus = is.read();
- skip(is, 4 - PARAM_CARD_READER_STATUS_LENGTH);
- }
- break;
- } // Fall through if TEST == false
+ // not needed for server role, but used for module test
+ if(paramLength != PARAM_CARD_READER_STATUS_LENGTH) {
+ Log.e(TAG, "Received PARAM_CARD_READER_STATUS with wrong length: " +
+ paramLength + " skipping this parameter.");
+ skip(is, paramLength + skipLen);
+ success = false;
+ } else {
+ mCardReaderStatus = is.read();
+ skip(is, 4 - PARAM_CARD_READER_STATUS_LENGTH);
+ }
+ break;
case PARAM_STATUS_CHANGE_ID:
- // not needed - server -> client
- if(TEST) {
- if(paramLength != PARAM_STATUS_CHANGE_LENGTH) {
- Log.e(TAG, "Received PARAM_STATUS_CHANGE with wrong length: " +
- paramLength + " skipping this parameter.");
- skip(is, paramLength + (4 - (paramLength % 4)));
- success = false;
- } else {
- mStatusChange = is.read();
- skip(is, 4 - PARAM_STATUS_CHANGE_LENGTH);
- }
- break;
- } // Fall through if TEST == false
+ // not needed for server role, but used for module test
+ if(paramLength != PARAM_STATUS_CHANGE_LENGTH) {
+ Log.e(TAG, "Received PARAM_STATUS_CHANGE with wrong length: " +
+ paramLength + " skipping this parameter.");
+ skip(is, paramLength + skipLen);
+ success = false;
+ } else {
+ mStatusChange = is.read();
+ skip(is, 4 - PARAM_STATUS_CHANGE_LENGTH);
+ }
+ break;
case PARAM_RESULT_CODE_ID:
- // not needed - server -> client
- if(TEST) {
- if(paramLength != PARAM_RESULT_CODE_LENGTH) {
- Log.e(TAG, "Received PARAM_RESULT_CODE with wrong length: " +
- paramLength + " skipping this parameter.");
- skip(is, paramLength + (4 - (paramLength % 4)));
- success = false;
- } else {
- mResultCode = is.read();
- skip(is, 4 - PARAM_RESULT_CODE_LENGTH);
- }
- break;
- } // Fall through if TEST == false
+ // not needed for server role, but used for module test
+ if(paramLength != PARAM_RESULT_CODE_LENGTH) {
+ Log.e(TAG, "Received PARAM_RESULT_CODE with wrong length: " +
+ paramLength + " skipping this parameter.");
+ skip(is, paramLength + skipLen);
+ success = false;
+ } else {
+ mResultCode = is.read();
+ skip(is, 4 - PARAM_RESULT_CODE_LENGTH);
+ }
+ break;
case PARAM_DISCONNECT_TYPE_ID:
- // not needed - server -> client
- if(TEST) {
- if(paramLength != PARAM_DISCONNECT_TYPE_LENGTH) {
- Log.e(TAG, "Received PARAM_DISCONNECT_TYPE_ID with wrong length: " +
- paramLength + " skipping this parameter.");
- skip(is, paramLength + (4 - (paramLength % 4)));
- success = false;
- } else {
- mDisconnectionType = is.read();
- skip(is, 4 - PARAM_DISCONNECT_TYPE_LENGTH);
- }
- break;
- } // Fall through if TEST == false
+ // not needed for server role, but used for module test
+ if(paramLength != PARAM_DISCONNECT_TYPE_LENGTH) {
+ Log.e(TAG, "Received PARAM_DISCONNECT_TYPE_ID with wrong length: " +
+ paramLength + " skipping this parameter.");
+ skip(is, paramLength + skipLen);
+ success = false;
+ } else {
+ mDisconnectionType = is.read();
+ skip(is, 4 - PARAM_DISCONNECT_TYPE_LENGTH);
+ }
+ break;
case PARAM_RESPONSE_APDU_ID:
- // not needed - server -> client
- if(TEST) {
- mApduResp = new byte[paramLength];
- read(is, mApduResp);
- skip(is, 4 - (paramLength % 4));
- break;
- } // Fall through if TEST == false
+ // not needed for server role, but used for module test
+ mApduResp = new byte[paramLength];
+ read(is, mApduResp);
+ skip(is, skipLen);
+ break;
case PARAM_ATR_ID:
- // not needed - server -> client
- if(TEST) {
- mAtr = new byte[paramLength];
- read(is, mAtr);
- skip(is, 4 - (paramLength % 4));
- break;
- } // Fall through if TEST == false
+ // not needed for server role, but used for module test
+ mAtr = new byte[paramLength];
+ read(is, mAtr);
+ skip(is, skipLen);
+ break;
default:
Log.e(TAG, "Received unknown parameter ID: " + paramId + " length: " +
paramLength + " skipping this parameter.");
- skip(is, paramLength + (4 - (paramLength % 4)));
+ skip(is, paramLength + skipLen);
}
}
return success;
@@ -643,8 +634,10 @@
/* Payload */
os.write(value);
- for(int i = 0, n = 4 - (value.length % 4) ; i < n; i++) {
- os.write(0); // Padding
+ if (value.length % 4 != 0) {
+ for (int i = 0; i < (4 - (value.length % 4)); ++i) {
+ os.write(0); // Padding
+ }
}
}
@@ -668,7 +661,7 @@
writeParameter(os, PARAM_RESULT_CODE_ID, mResultCode,
PARAM_RESULT_CODE_LENGTH);
}
- if(mDisconnectionType != INVALID_VALUE && TEST) {
+ if(mDisconnectionType != INVALID_VALUE) {
writeParameter(os, PARAM_DISCONNECT_TYPE_ID, mDisconnectionType,
PARAM_DISCONNECT_TYPE_LENGTH);
}
@@ -680,14 +673,14 @@
writeParameter(os, PARAM_STATUS_CHANGE_ID, mStatusChange,
PARAM_STATUS_CHANGE_LENGTH);
}
- if(mTransportProtocol != INVALID_VALUE && TEST) {
+ if(mTransportProtocol != INVALID_VALUE) {
writeParameter(os, PARAM_TRANSPORT_PROTOCOL_ID, mTransportProtocol,
PARAM_TRANSPORT_PROTOCOL_LENGTH);
}
- if(mApdu != null && TEST) {
+ if(mApdu != null) {
writeParameter(os, PARAM_COMMAND_APDU_ID, mApdu);
}
- if(mApdu7816 != null && TEST) {
+ if(mApdu7816 != null) {
writeParameter(os, PARAM_COMMAND_APDU7816_ID, mApdu7816);
}
if(mApduResp != null) {
@@ -838,10 +831,8 @@
break;
}
default:
- if(TEST == false) {
- Log.e(TAG, "Unknown request type");
- throw new IllegalArgumentException();
- }
+ Log.e(TAG, "Unknown request type");
+ throw new IllegalArgumentException();
}
/* Update the ongoing requests queue */
if(mClearRilQueue == true) {
@@ -1214,7 +1205,7 @@
public static String getMsgTypeName(int msgType) {
- if(TEST || VERBOSE) {
+ if(DEBUG || VERBOSE) {
switch (msgType)
{
case ID_CONNECT_REQ: return "ID_CONNECT_REQ";
diff --git a/src/com/android/bluetooth/sap/SapServer.java b/src/com/android/bluetooth/sap/SapServer.java
index 4135a26..339f676 100644
--- a/src/com/android/bluetooth/sap/SapServer.java
+++ b/src/com/android/bluetooth/sap/SapServer.java
@@ -8,6 +8,7 @@
import java.util.concurrent.CountDownLatch;
import com.android.bluetooth.R;
+
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -26,8 +27,10 @@
import android.os.Message;
import android.os.Parcel;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.telephony.TelephonyManager;
import android.util.Log;
+
//import com.android.internal.telephony.RIL;
import com.google.protobuf.micro.CodedOutputStreamMicro;
@@ -48,7 +51,6 @@
private static final String TAG_HANDLER = "SapServerHandler";
public static final boolean DEBUG = SapService.DEBUG;
public static final boolean VERBOSE = SapService.VERBOSE;
- public static final boolean PTS_TEST = SapService.PTS_TEST;
private enum SAP_STATE {
DISCONNECTED, CONNECTING, CONNECTING_CALL_ONGOING, CONNECTED,
@@ -212,6 +214,13 @@
String title, text, button, ticker;
Notification notification;
if(VERBOSE) Log.i(TAG, "setNotification type: " + type);
+ /* For PTS TC_SERVER_DCN_BV_03_I we need to expose the option to send immediate disconnect
+ * without first sending a graceful disconnect.
+ * To enable this option set
+ * bt.sap.pts="true" */
+ String pts_enabled = SystemProperties.get("bt.sap.pts");
+ Boolean pts_test = Boolean.parseBoolean(pts_enabled);
+
/* put notification up for the user to be able to disconnect from the client*/
Intent sapDisconnectIntent = new Intent(SapServer.SAP_DISCONNECT_ACTION);
if(type == SapMessage.DISC_GRACEFULL){
@@ -225,7 +234,7 @@
text = mContext.getString(R.string.bluetooth_sap_notif_disconnecting);
ticker = mContext.getString(R.string.bluetooth_sap_notif_ticker);
}
- if(!PTS_TEST)
+ if(!pts_test)
{
sapDisconnectIntent.putExtra(SapServer.SAP_DISCONNECT_TYPE_EXTRA, type);
PendingIntent pIntentDisconnect = PendingIntent.getBroadcast(mContext, type,
@@ -413,7 +422,10 @@
* - Initiate a FORCED shutdown
* - Wait for RIL deinit to complete
*/
- if(mState != SAP_STATE.DISCONNECTED) {
+ if (mState == SAP_STATE.CONNECTING_CALL_ONGOING) {
+ /* Most likely remote device closed rfcomm, update state */
+ changeState(SAP_STATE.DISCONNECTED);
+ } else if (mState != SAP_STATE.DISCONNECTED) {
if(mState != SAP_STATE.DISCONNECTING &&
mIsLocalInitDisconnect != true) {
sendDisconnectInd(SapMessage.DISC_FORCED);
@@ -500,7 +512,6 @@
if (isCallOngoing() == true) {
/* If a call is ongoing we set the state, inform the SAP client and wait for a state
* change intent from the TelephonyManager with state IDLE. */
- changeState(SAP_STATE.CONNECTING_CALL_ONGOING);
reply.setConnectionStatus(SapMessage.CON_STATUS_OK_ONGOING_CALL);
} else {
/* no call is ongoing, initiate the connect sequence:
@@ -642,11 +653,12 @@
if(DEBUG) Log.i(TAG_HANDLER, "in Shutdown()");
try {
- mRfcommOut.close();
+ if (mRfcommOut != null)
+ mRfcommOut.close();
} catch (IOException e) {}
try {
- mRfcommIn.close();
-
+ if (mRfcommIn != null)
+ mRfcommIn.close();
} catch (IOException e) {}
mRfcommIn = null;
mRfcommOut = null;
@@ -705,19 +717,25 @@
switch(sapMsg.getMsgType()) {
case SapMessage.ID_CONNECT_RESP:
- if (sapMsg.getConnectionStatus() == SapMessage.CON_STATUS_OK) {
- // This is successful connect response from RIL/modem.
- changeState(SAP_STATE.CONNECTED);
- } else if(sapMsg.getConnectionStatus() == SapMessage.CON_STATUS_OK_ONGOING_CALL
- && mState != SAP_STATE.CONNECTING_CALL_ONGOING) {
- changeState(SAP_STATE.CONNECTING_CALL_ONGOING);
- } else if(mState == SAP_STATE.CONNECTING_CALL_ONGOING) {
+ if(mState == SAP_STATE.CONNECTING_CALL_ONGOING) {
/* Hold back the connect resp if a call was ongoing when the connect req
- * was received.
+ * was received.
+ * A response with status call-ongoing was sent, and the connect response
+ * received from the RIL when call ends must be discarded.
*/
+ if (sapMsg.getConnectionStatus() == SapMessage.CON_STATUS_OK) {
+ // This is successful connect response from RIL/modem.
+ changeState(SAP_STATE.CONNECTED);
+ }
if(VERBOSE) Log.i(TAG, "Hold back the connect resp, as a call was ongoing" +
" when the initial response were sent.");
sapMsg = null;
+ } else if (sapMsg.getConnectionStatus() == SapMessage.CON_STATUS_OK) {
+ // This is successful connect response from RIL/modem.
+ changeState(SAP_STATE.CONNECTED);
+ } else if(sapMsg.getConnectionStatus() ==
+ SapMessage.CON_STATUS_OK_ONGOING_CALL) {
+ changeState(SAP_STATE.CONNECTING_CALL_ONGOING);
} else if(sapMsg.getConnectionStatus() != SapMessage.CON_STATUS_OK) {
/* Most likely the peer will try to connect again, hence we keep the
* connection to RIL open and stay in connecting state.
@@ -822,11 +840,18 @@
if(VERBOSE) Log.i(TAG_HANDLER, "sendRilMessage() - "
+ SapMessage.getMsgTypeName(sapMsg.getMsgType()));
try {
- sapMsg.writeReqToStream(mRilBtOutStream);
+ if(mRilBtOutStream != null) {
+ sapMsg.writeReqToStream(mRilBtOutStream);
+ } /* Else SAP was enabled on a build that did not support SAP, which we will not
+ * handle. */
} catch (IOException e) {
Log.e(TAG_HANDLER, "Unable to send message to RIL", e);
SapMessage errorReply = new SapMessage(SapMessage.ID_ERROR_RESP);
sendClientMessage(errorReply);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG_HANDLER, "Unable encode message", e);
+ SapMessage errorReply = new SapMessage(SapMessage.ID_ERROR_RESP);
+ sendClientMessage(errorReply);
}
}
diff --git a/src/com/android/bluetooth/sap/SapService.java b/src/com/android/bluetooth/sap/SapService.java
index d5caf80..23d69ff 100644
--- a/src/com/android/bluetooth/sap/SapService.java
+++ b/src/com/android/bluetooth/sap/SapService.java
@@ -47,7 +47,6 @@
private static final String TAG = "SapService";
public static final boolean DEBUG = false;
public static final boolean VERBOSE = false;
- public static final boolean PTS_TEST = false;
/* Message ID's */
private static final int START_LISTENER = 1;