diff options
author | Steve Kondik <shade@chemlab.org> | 2014-04-17 02:47:56 -0700 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2014-04-17 03:19:00 -0700 |
commit | 3c99a1e84c0a529310c1892d928eb3824e0e47be (patch) | |
tree | 8da328a4c2fc59e88b4b4774aca8360717cfc22b | |
parent | 35743ee540dd399a19929b75cdf8e13a0461c4ff (diff) | |
parent | 91ba9534bf14cd141071d4a88019f582115fce87 (diff) | |
download | android_packages_apps_Bluetooth-next.tar.gz android_packages_apps_Bluetooth-next.tar.bz2 android_packages_apps_Bluetooth-next.zip |
Merge branch 'LNX.LA.3.5.2_RB1' of git://codeaurora.org/platform/packages/apps/Bluetooth into cm-11.0next
Change-Id: I2452b5410e87fa2ef0d09d5929e5813622f17d5b
24 files changed, 245 insertions, 114 deletions
diff --git a/jni/com_android_bluetooth_a2dp.cpp b/jni/com_android_bluetooth_a2dp.cpp index 76f90d6a4..babdf9864 100644 --- a/jni/com_android_bluetooth_a2dp.cpp +++ b/jni/com_android_bluetooth_a2dp.cpp @@ -305,7 +305,7 @@ static void informAudioFocusStateNative(JNIEnv *env, jobject object, int state) } -static jboolean isSrcNative(JNIEnv *env, jobject object, jbyteArray address) { +static jint isSrcNative(JNIEnv *env, jobject object, jbyteArray address) { jbyte *addr; bt_status_t status; @@ -321,7 +321,7 @@ static jboolean isSrcNative(JNIEnv *env, jobject object, jbyteArray address) { ALOGE("Failed HF disconnection, status: %d", status); } env->ReleaseByteArrayElements(address, addr, 0); - return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; + return status; } static void suspendA2dpNative(JNIEnv *env, jobject object) { @@ -352,7 +352,7 @@ static JNINativeMethod sMethods[] = { {"connectA2dpNative", "([B)Z", (void *) connectA2dpNative}, {"disconnectA2dpNative", "([B)Z", (void *) disconnectA2dpNative}, {"allowConnectionNative", "(I)V", (void *) allowConnectionNative}, - {"isSrcNative", "([B)Z", (void *) isSrcNative}, + {"isSrcNative", "([B)I", (void *) isSrcNative}, {"suspendA2dpNative", "()V", (void *) suspendA2dpNative}, {"resumeA2dpNative", "()V", (void *) resumeA2dpNative}, {"informAudioFocusStateNative", "(I)V", (void *) informAudioFocusStateNative}, diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java index 902b6849c..22c6081b9 100644 --- a/src/com/android/bluetooth/a2dp/A2dpService.java +++ b/src/com/android/bluetooth/a2dp/A2dpService.java @@ -201,6 +201,28 @@ public class A2dpService extends ProfileService { return priority; } + public boolean setLastConnectedA2dpSepType(BluetoothDevice device, int sepType) { + enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, + "Need BLUETOOTH_ADMIN permission"); + + Log.d(TAG,"setLastConnectedA2dpSepType: " + sepType); + + Settings.Global.putInt(getContentResolver(), + Settings.Global.getBluetoothLastConnectedA2dpSepTypeKey(device.getAddress()), + sepType); + return true; + } + + public int getLastConnectedA2dpSepType(BluetoothDevice device) { + enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, + "Need BLUETOOTH_ADMIN permission"); + int sepType = Settings.Global.getInt(getContentResolver(), + Settings.Global.getBluetoothLastConnectedA2dpSepTypeKey(device.getAddress()), + BluetoothProfile.PROFILE_A2DP_UNDEFINED); + return sepType; + } + + /* Absolute volume implementation */ public boolean isAvrcpAbsoluteVolumeSupported() { return mAvrcp.isAbsoluteVolumeSupported(); diff --git a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java index 642a0a228..fc1f3ec02 100644 --- a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java +++ b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java @@ -52,6 +52,7 @@ import android.os.ParcelUuid; import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.btservice.AbstractionLayer; import com.android.bluetooth.btservice.ProfileService; import com.android.internal.util.IState; import com.android.internal.util.State; @@ -560,6 +561,11 @@ final class A2dpStateMachine extends StateMachine { BluetoothProfile.STATE_DISCONNECTING); break; } + if (mPlayingA2dpDevice != null) { + broadcastAudioState(mPlayingA2dpDevice, BluetoothA2dp.STATE_NOT_PLAYING, + BluetoothA2dp.STATE_PLAYING); + mPlayingA2dpDevice = null; + } transitionTo(mPending); } break; @@ -609,7 +615,8 @@ final class A2dpStateMachine extends StateMachine { loge("Disconnected from unknown device: " + device); } - if (isSrcNative(getByteAddress(device))) { + if (isSrcNative(getByteAddress(device)) + == AbstractionLayer.BT_STATUS_SUCCESS) { // in case PEER DEVICE is A2DP SRC we need to manager audio focus int status = mAudioManager.abandonAudioFocus(mAudioFocusListener); log("Status loss returned " + status); @@ -625,7 +632,8 @@ final class A2dpStateMachine extends StateMachine { private void processAudioFocusRequestEvent(int enable, BluetoothDevice device) { if (mPlayingA2dpDevice != null) { - if ((isSrcNative(getByteAddress(device))) && (enable == 1)){ + if ((isSrcNative(getByteAddress(device)) + == AbstractionLayer.BT_STATUS_SUCCESS) && (enable == 1)){ // in case PEER DEVICE is A2DP SRC we need to manager audio focus int status = mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN); @@ -667,9 +675,14 @@ final class A2dpStateMachine extends StateMachine { } } + // true if peer device is source boolean isConnectedSrc(BluetoothDevice device) { - return isSrcNative(getByteAddress(device)); + if (isSrcNative(getByteAddress(device)) + == AbstractionLayer.BT_STATUS_SUCCESS) + return true; + else + return false; } int getConnectionState(BluetoothDevice device) { @@ -768,17 +781,31 @@ final class A2dpStateMachine extends StateMachine { // This method does not check for error conditon (newState == prevState) private void broadcastConnectionState(BluetoothDevice device, int newState, int prevState) { - int delay; - // in case PEER DEVICE is A2DP SRC we don't need to tell AUDIO - if (!isSrcNative(getByteAddress(device))) { + int delay = 0; + // in case PEER DEVICE is A2DP SNK we need to tell AUDIO + if (isSrcNative(getByteAddress(device)) + == AbstractionLayer.BT_STATUS_FAIL) { + // do not update delay for disconecting as by time disconnect comes + // Sep end point is cleared delay = mAudioManager.setBluetoothA2dpDeviceConnectionState(device, newState); + if (newState == BluetoothProfile.STATE_DISCONNECTING) + delay = 0; log("Peer Device is SNK"); + if (newState == BluetoothProfile.STATE_CONNECTED) { + mService.setLastConnectedA2dpSepType (device, + BluetoothProfile.PROFILE_A2DP_SNK); + } } else { - delay = 0; log("Peer Device is SRC"); + if (newState == BluetoothProfile.STATE_CONNECTED) { + mService.setLastConnectedA2dpSepType (device, + BluetoothProfile.PROFILE_A2DP_SRC); + } + log("Peer Device is SRC/Not ready yet"); } mWakeLock.acquire(); + log("delay is " + delay + "for device " + device); mIntentBroadcastHandler.sendMessageDelayed(mIntentBroadcastHandler.obtainMessage( MSG_CONNECTION_STATE_CHANGED, prevState, @@ -888,7 +915,8 @@ final class A2dpStateMachine extends StateMachine { log("Command Received " + cmd); if (cmd.equals("pause")) { if (mCurrentDevice != null) { - if (isSrcNative(getByteAddress(mCurrentDevice))) { + if (isSrcNative(getByteAddress(mCurrentDevice)) + == AbstractionLayer.BT_STATUS_SUCCESS) { //Camera Pauses the Playback before starting the Video recording //But it doesn't start the playback once recording is completed. //Disconnecting the A2dp to move the A2dpSink to proper state. @@ -912,7 +940,8 @@ final class A2dpStateMachine extends StateMachine { switch(focusChange){ case AudioManager.AUDIOFOCUS_LOSS: if (mCurrentDevice != null) { - if (isSrcNative(getByteAddress(mCurrentDevice))) { + if (isSrcNative(getByteAddress(mCurrentDevice)) + == AbstractionLayer.BT_STATUS_SUCCESS) { // in case of perm loss, disconnect the link disconnectA2dpNative(getByteAddress(mCurrentDevice)); // in case PEER DEVICE is A2DP SRC we need to manage audio focus @@ -973,7 +1002,7 @@ final class A2dpStateMachine extends StateMachine { private native boolean connectA2dpNative(byte[] address); private native boolean disconnectA2dpNative(byte[] address); private native void allowConnectionNative(int isValid); - private native boolean isSrcNative(byte[] address); + private native int isSrcNative(byte[] address); private native void suspendA2dpNative(); private native void resumeA2dpNative(); private native void informAudioFocusStateNative(int state); diff --git a/src/com/android/bluetooth/a2dp/Avrcp.java b/src/com/android/bluetooth/a2dp/Avrcp.java index 6533b935b..f2d559801 100644 --- a/src/com/android/bluetooth/a2dp/Avrcp.java +++ b/src/com/android/bluetooth/a2dp/Avrcp.java @@ -875,12 +875,15 @@ final class Avrcp { } private void updateAddressedMediaPlayer(int playerId) { if (DEBUG) Log.v(TAG, "updateAddressedMediaPlayer"); + int previousAddressedPlayerId = mAddressedPlayerId; if ((mAddressedPlayerChangedNT == NOTIFICATION_TYPE_INTERIM) && (mAddressedPlayerId != playerId)) { if (DEBUG) Log.v(TAG, "send AddressedMediaPlayer to stack: playerId" + playerId); mAddressedPlayerId = playerId; mAddressedPlayerChangedNT = NOTIFICATION_TYPE_CHANGED; registerNotificationRspAddressedPlayerChangedNative(mAddressedPlayerChangedNT, mAddressedPlayerId); - resetAndSendPlayerStatusReject(); + if (previousAddressedPlayerId != 0) { + resetAndSendPlayerStatusReject(); + } } else { mAddressedPlayerId = playerId; } diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java index 88066c5e8..a62a20729 100644 --- a/src/com/android/bluetooth/btservice/AdapterService.java +++ b/src/com/android/bluetooth/btservice/AdapterService.java @@ -1279,6 +1279,7 @@ public class AdapterService extends Service { } else if((a2dpConnDevList.isEmpty()) && (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && + (a2dpService.getLastConnectedA2dpSepType(device) == BluetoothProfile.PROFILE_A2DP_SNK)&& (hsConnected || (hsService.getPriority(device) == BluetoothProfile.PRIORITY_OFF))) { a2dpService.connect(device); } diff --git a/src/com/android/bluetooth/btservice/AdapterState.java b/src/com/android/bluetooth/btservice/AdapterState.java index 888e47c06..1d5eff99f 100644 --- a/src/com/android/bluetooth/btservice/AdapterState.java +++ b/src/com/android/bluetooth/btservice/AdapterState.java @@ -24,6 +24,7 @@ import android.util.Log; import com.android.internal.util.State; import com.android.internal.util.StateMachine; +import android.os.SystemProperties; /** * This state machine handles Bluetooth Adapter State. @@ -375,9 +376,11 @@ final class AdapterState extends StateMachine { void stateChangeCallback(int status) { if (status == AbstractionLayer.BT_STATE_OFF) { + SystemProperties.set("bluetooth.isEnabled","false"); sendMessage(DISABLED); } else if (status == AbstractionLayer.BT_STATE_ON) { // We should have got the property change for adapter and remote devices. + SystemProperties.set("bluetooth.isEnabled","true"); sendMessage(ENABLED_READY); } else { errorLog("Incorrect status in stateChangeCallback"); diff --git a/src/com/android/bluetooth/btservice/RemoteDevices.java b/src/com/android/bluetooth/btservice/RemoteDevices.java index e4c01fef5..2898145df 100644 --- a/src/com/android/bluetooth/btservice/RemoteDevices.java +++ b/src/com/android/bluetooth/btservice/RemoteDevices.java @@ -308,7 +308,7 @@ final class RemoteDevices { intent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, pin); intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN); - mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM); + mAdapterService.sendOrderedBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM); // Release wakelock to allow the LCD to go off after the PIN popup notification. mWakeLock.release(); } @@ -448,7 +448,7 @@ final class RemoteDevices { intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN); intent.putExtra(BluetoothDevice.EXTRA_SECURE_PAIRING, secure); - mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM); + mAdapterService.sendOrderedBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM); // Release wakelock to allow the LCD to go off after the PIN popup notification. mWakeLock.release(); return; @@ -495,7 +495,7 @@ final class RemoteDevices { intent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, passkey); } intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, variant); - mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM); + mAdapterService.sendOrderedBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM); // Release wakelock to allow the LCD to go off after the PIN popup notification. mWakeLock.release(); diff --git a/src/com/android/bluetooth/hdp/HealthService.java b/src/com/android/bluetooth/hdp/HealthService.java index c09e92a6b..9ca76a489 100644 --- a/src/com/android/bluetooth/hdp/HealthService.java +++ b/src/com/android/bluetooth/hdp/HealthService.java @@ -112,15 +112,16 @@ public class HealthService extends ProfileService { } private void cleanupApps(){ - Iterator <Map.Entry<BluetoothHealthAppConfiguration,AppInfo>>it - = mApps.entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry<BluetoothHealthAppConfiguration,AppInfo> entry = it.next(); - AppInfo appInfo = entry.getValue(); - if (appInfo != null) - appInfo.cleanup(); - it.remove(); + if (mApps != null) { + Iterator <Map.Entry<BluetoothHealthAppConfiguration,AppInfo>>it + = mApps.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry<BluetoothHealthAppConfiguration,AppInfo> entry = it.next(); + AppInfo appInfo = entry.getValue(); + if (appInfo != null) + appInfo.cleanup(); + it.remove(); + } } } protected boolean cleanup() { diff --git a/src/com/android/bluetooth/hfp/AtPhonebook.java b/src/com/android/bluetooth/hfp/AtPhonebook.java index 952bbc900..aafc7cc5f 100755..100644 --- a/src/com/android/bluetooth/hfp/AtPhonebook.java +++ b/src/com/android/bluetooth/hfp/AtPhonebook.java @@ -31,8 +31,6 @@ import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.PhoneLookup; import android.telephony.PhoneNumberUtils; import android.util.Log; -import com.android.bluetooth.Utils; - import java.util.HashMap; @@ -149,11 +147,7 @@ public class AtPhonebook { mCpbrIndex1 = mCpbrIndex2 = cpbrIndex; } - private byte[] getByteAddress(BluetoothDevice device) { - return Utils.getBytesFromAddress(device.getAddress()); - } - - public void handleCscsCommand(String atString, int type, BluetoothDevice device) + public void handleCscsCommand(String atString, int type) { log("handleCscsCommand - atString = " +atString); // Select Character Set @@ -194,12 +188,11 @@ public class AtPhonebook { atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS; } if (atCommandResponse != null) - mStateMachine.atResponseStringNative(atCommandResponse, getByteAddress(device)); - mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode, - getByteAddress(device)); + mStateMachine.atResponseStringNative(atCommandResponse); + mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode); } - public void handleCpbsCommand(String atString, int type, BluetoothDevice device) { + public void handleCpbsCommand(String atString, int type) { // Select PhoneBook memory Storage log("handleCpbsCommand - atString = " +atString); int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR; @@ -220,11 +213,10 @@ public class AtPhonebook { break; } int size = pbr.cursor.getCount(); - atCommandResponse = "+CPBS: \"" + mCurrentPhonebook + - "\"," + size + "," + getMaxPhoneBookSize(size); - atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; + atCommandResponse = "+CPBS: \"" + mCurrentPhonebook + "\"," + size + "," + getMaxPhoneBookSize(size); pbr.cursor.close(); pbr.cursor = null; + atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; break; case TYPE_TEST: // Test log("handleCpbsCommand - test command"); @@ -256,9 +248,8 @@ public class AtPhonebook { atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS; } if (atCommandResponse != null) - mStateMachine.atResponseStringNative(atCommandResponse, getByteAddress(device)); - mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode, - getByteAddress(device)); + mStateMachine.atResponseStringNative(atCommandResponse); + mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode); } public void handleCpbrCommand(String atString, int type, BluetoothDevice remoteDevice) { @@ -310,7 +301,7 @@ public class AtPhonebook { int index1; int index2; if ((atString.split("=")).length < 2) { - atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_SUPPORTED; + mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode); break; } String atCommand = (atString.split("="))[1]; @@ -328,6 +319,7 @@ public class AtPhonebook { catch (Exception e) { log("handleCpbrCommand - exception - invalid chars: " + e.toString()); atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS; + mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode); break; } mCpbrIndex1 = index1; @@ -336,22 +328,20 @@ public class AtPhonebook { if (checkAccessPermission(remoteDevice)) { mCheckingAccessPermission = false; - atCommandResult = processCpbrCommand(remoteDevice); + atCommandResult = processCpbrCommand(); mCpbrIndex1 = mCpbrIndex2 = -1; break; } // no reponse here, will continue the process in handleAccessPermissionResult break; - case TYPE_UNKNOWN: - default: + case TYPE_UNKNOWN: + default: log("handleCpbrCommand - invalid chars"); atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS; - break; } if (atCommandResponse != null) - mStateMachine.atResponseStringNative(atCommandResponse, getByteAddress(remoteDevice)); - mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode, - getByteAddress(remoteDevice)); + mStateMachine.atResponseStringNative(atCommandResponse); + mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode); } /** Get the most recent result for the given phone book, @@ -452,7 +442,7 @@ public class AtPhonebook { } // process CPBR command after permission check - /*package*/ int processCpbrCommand(BluetoothDevice device) + /*package*/ int processCpbrCommand() { log("processCpbrCommand"); int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR; @@ -556,7 +546,7 @@ public class AtPhonebook { record = record + "\r\n\r\n"; atCommandResponse = record; log("processCpbrCommand - atCommandResponse = "+atCommandResponse); - mStateMachine.atResponseStringNative(atCommandResponse, getByteAddress(device)); + mStateMachine.atResponseStringNative(atCommandResponse); if (!pbr.cursor.moveToNext()) { break; } diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java index c429d627c..19f09d560 100644 --- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java +++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java @@ -334,6 +334,8 @@ final class HeadsetStateMachine extends StateMachine { log("Enter Disconnected: " + getCurrentMessage().what); mPhonebook.resetAtState(); mPhoneState.listenForPhoneState(false); + mVoiceRecognitionStarted = false; + mWaitingForVoiceRecognition = false; } @Override diff --git a/src/com/android/bluetooth/hfpclient/HandsfreeClientStateMachine.java b/src/com/android/bluetooth/hfpclient/HandsfreeClientStateMachine.java index b35a9bbaa..32132e4ec 100644 --- a/src/com/android/bluetooth/hfpclient/HandsfreeClientStateMachine.java +++ b/src/com/android/bluetooth/hfpclient/HandsfreeClientStateMachine.java @@ -704,7 +704,6 @@ final class HandsfreeClientStateMachine extends StateMachine { if (mQueryCallsSupported) { sendMessage(QUERY_CURRENT_CALLS); - return; } BluetoothHandsfreeClientCall c = null; @@ -952,9 +951,6 @@ final class HandsfreeClientStateMachine extends StateMachine { } break; case BluetoothHandsfreeClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD: - if (flag != BluetoothHandsfreeClient.CALL_ACCEPT_NONE) { - return; - } action = HandsfreeClientHalConstants.CALL_ACTION_BTRH_1; break; case BluetoothHandsfreeClientCall.CALL_STATE_ALERTING: diff --git a/src/com/android/bluetooth/map/BluetoothMapAppParams.java b/src/com/android/bluetooth/map/BluetoothMapAppParams.java index eb7b9d68b..ab31e476c 100644 --- a/src/com/android/bluetooth/map/BluetoothMapAppParams.java +++ b/src/com/android/bluetooth/map/BluetoothMapAppParams.java @@ -699,7 +699,7 @@ public class BluetoothMapAppParams { if(parameterMask == 0) { this.parameterMask = INVALID_VALUE_PARAMETER; } else { - this.parameterMask = parameterMask; + this.parameterMask = parameterMask; } } diff --git a/src/com/android/bluetooth/map/BluetoothMapContent.java b/src/com/android/bluetooth/map/BluetoothMapContent.java index 9092174db..19447980c 100644 --- a/src/com/android/bluetooth/map/BluetoothMapContent.java +++ b/src/com/android/bluetooth/map/BluetoothMapContent.java @@ -870,28 +870,30 @@ public class BluetoothMapContent { private void setDateTime(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, BluetoothMapAppParams ap) { - long date = 0; - int timeStamp = 0; + if ((ap.getParameterMask() & MASK_DATETIME) != 0) { + long date = 0; + int timeStamp = 0; - if (fi.msgType == FilterInfo.TYPE_SMS) { - date = c.getLong(c.getColumnIndex(Sms.DATE)); - } else if (fi.msgType == FilterInfo.TYPE_MMS) { - /* Use Mms.DATE for all messages. Although contract class states */ - /* Mms.DATE_SENT are for outgoing messages. But that is not working. */ - date = c.getLong(c.getColumnIndex(Mms.DATE)) * 1000L; - - /* int msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); */ - /* if (msgBox == Mms.MESSAGE_BOX_INBOX) { */ - /* date = c.getLong(c.getColumnIndex(Mms.DATE)) * 1000L; */ - /* } else { */ - /* date = c.getLong(c.getColumnIndex(Mms.DATE_SENT)) * 1000L; */ - /* } */ - } else { - timeStamp = c.getColumnIndex(MessageColumns.TIMESTAMP); - String timestamp = c.getString(timeStamp); - date =Long.valueOf(timestamp); + if (fi.msgType == FilterInfo.TYPE_SMS) { + date = c.getLong(c.getColumnIndex(Sms.DATE)); + } else if (fi.msgType == FilterInfo.TYPE_MMS) { + /* Use Mms.DATE for all messages. Although contract class states */ + /* Mms.DATE_SENT are for outgoing messages. But that is not working. */ + date = c.getLong(c.getColumnIndex(Mms.DATE)) * 1000L; + + /* int msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); */ + /* if (msgBox == Mms.MESSAGE_BOX_INBOX) { */ + /* date = c.getLong(c.getColumnIndex(Mms.DATE)) * 1000L; */ + /* } else { */ + /* date = c.getLong(c.getColumnIndex(Mms.DATE_SENT)) * 1000L; */ + /* } */ + } else { + timeStamp = c.getColumnIndex(MessageColumns.TIMESTAMP); + String timestamp = c.getString(timeStamp); + date =Long.valueOf(timestamp); + } + e.setDateTime(date); } - e.setDateTime(date); } private String getTextPartsMms(long id) { @@ -2222,8 +2224,14 @@ public class BluetoothMapContent { case SMS_CDMA: return getSmsMessage(id, appParams.getCharset()); case MMS: + if(appParams.getCharset()== MAP_MESSAGE_CHARSET_NATIVE) { + throw new IllegalArgumentException("Invalid Charset: Native for Message Type MMS"); + } return getMmsMessage(id, appParams); case EMAIL: + if(appParams.getCharset()== MAP_MESSAGE_CHARSET_NATIVE) { + throw new IllegalArgumentException("Invalid Charset: Native for Message Type Email"); + } return getEmailMessage(id, appParams); } throw new IllegalArgumentException("Invalid message handle."); @@ -2232,7 +2240,7 @@ public class BluetoothMapContent { private void setVCardFromEmailAddress(BluetoothMapbMessage message, String emailAddr, boolean incoming) { if(D) Log.d(TAG, "setVCardFromEmailAddress, emailAdress is " +emailAddr); String contactId = null, contactName = null; - String[] phoneNumbers = null; + String[] phoneNumbers = {""}; String[] emailAddresses = new String[1]; StringTokenizer emailId; Cursor p; diff --git a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java index 8d56d3398..052188e66 100644 --- a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +++ b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java @@ -1004,8 +1004,13 @@ public class BluetoothMapContentObserver { private void writeMmsDataPart(long handle, MimePart part, int count) throws IOException{ ContentValues values = new ContentValues(); values.put("mid", handle); - if(part.contentType != null) + if(part.contentType != null){ + //Remove last char if ';' from contentType + if(part.contentType.charAt(part.contentType.length() - 1) == ';') { + part.contentType = part.contentType.substring(0,part.contentType.length() -1); + } values.put("ct", part.contentType); + } if(part.contentId != null) values.put("cid", part.contentId); if(part.contentLocation != null) diff --git a/src/com/android/bluetooth/map/BluetoothMapObexServer.java b/src/com/android/bluetooth/map/BluetoothMapObexServer.java index a33ea8562..7d9558884 100644 --- a/src/com/android/bluetooth/map/BluetoothMapObexServer.java +++ b/src/com/android/bluetooth/map/BluetoothMapObexServer.java @@ -852,7 +852,9 @@ public class BluetoothMapObexServer extends ServerRequestHandler { Log.w(TAG,"sendGetMessageRsp: IOException - sending OBEX_HTTP_BAD_REQUEST", e); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } catch (IllegalArgumentException e) { - Log.w(TAG,"sendGetMessageRsp: IllegalArgumentException (e.g. invalid handle) - sending OBEX_HTTP_BAD_REQUEST", e); + Log.w(TAG, + "sendGetMessageRsp: IllegalArgumentException (e.g. invalid handle or charset) - sending OBEX_HTTP_BAD_REQUEST" + , e); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } diff --git a/src/com/android/bluetooth/map/BluetoothMapbMessageMmsEmail.java b/src/com/android/bluetooth/map/BluetoothMapbMessageMmsEmail.java index 2dda7e24e..84f9c511e 100644 --- a/src/com/android/bluetooth/map/BluetoothMapbMessageMmsEmail.java +++ b/src/com/android/bluetooth/map/BluetoothMapbMessageMmsEmail.java @@ -416,7 +416,6 @@ public class BluetoothMapbMessageMmsEmail extends BluetoothMapbMessage { } emailBody = sb.toString(); - if (V) Log.v(TAG, "emailBody is "+emailBody); if(emailBody != null) { String tmpBody = emailBody.replaceAll("END:MSG", "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG @@ -742,6 +741,7 @@ public class BluetoothMapbMessageMmsEmail extends BluetoothMapbMessage { throw new IllegalArgumentException("Ill-formatted bMessage, no END:MSG"); } setEmailBody(body.substring(beginMsg + "BEGIN:MSG".length(), endMsg - CRLF.length())); + break; } else { pos = next + CRLF.length(); } @@ -759,11 +759,11 @@ public class BluetoothMapbMessageMmsEmail extends BluetoothMapbMessage { } } else { endVersionPos = (body.indexOf("--"+boundary+"--", beginVersionPos) - CRLF.length()); - } - try { - setEmailBody(body.substring(beginVersionPos, endVersionPos)); - } catch (IndexOutOfBoundsException e) { - throw new IllegalArgumentException("Ill-formatted bMessage, no end boundary"); + try { + setEmailBody(body.substring(beginVersionPos, endVersionPos)); + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException("Ill-formatted bMessage, no end boundary"); + } } } else if(rfc822Flag == 1) { endVersionPos = (body.indexOf("--"+boundary+"--", beginVersionPos)); diff --git a/src/com/android/bluetooth/opp/BluetoothOppManager.java b/src/com/android/bluetooth/opp/BluetoothOppManager.java index dc4d8acac..849abf36a 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppManager.java +++ b/src/com/android/bluetooth/opp/BluetoothOppManager.java @@ -253,11 +253,13 @@ public class BluetoothOppManager { synchronized (BluetoothOppManager.this) { mMultipleFlag = false; mMimeTypeOfSendingFile = mimeType; - mUriOfSendingFile = uriString; mIsHandoverInitiated = isHandover; Uri uri = Uri.parse(uriString); - BluetoothOppUtility.putSendFileInfo(uri, - BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType)); + BluetoothOppSendFileInfo sendFileInfo = + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType); + uri = BluetoothOppUtility.generateUri(uri, sendFileInfo); + BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo); + mUriOfSendingFile = uri.toString(); storeApplicationData(); } } @@ -266,11 +268,14 @@ public class BluetoothOppManager { synchronized (BluetoothOppManager.this) { mMultipleFlag = true; mMimeTypeOfSendingFiles = mimeType; - mUrisOfSendingFiles = uris; + mUrisOfSendingFiles = new ArrayList<Uri>(); mIsHandoverInitiated = isHandover; for (Uri uri : uris) { - BluetoothOppUtility.putSendFileInfo(uri, - BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType)); + BluetoothOppSendFileInfo sendFileInfo = + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType); + uri = BluetoothOppUtility.generateUri(uri, sendFileInfo); + mUrisOfSendingFiles.add(uri); + BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo); } storeApplicationData(); } @@ -429,17 +434,18 @@ public class BluetoothOppManager { Long ts = System.currentTimeMillis(); for (int i = 0; i < count; i++) { Uri fileUri = mUris.get(i); + + BluetoothOppSendFileInfo fileInfo = BluetoothOppUtility.getSendFileInfo(fileUri); + ContentValues values = new ContentValues(); + values.put(BluetoothShare.URI, fileUri.toString()); + ContentResolver contentResolver = mContext.getContentResolver(); + fileUri = BluetoothOppUtility.originalUri(fileUri); String contentType = contentResolver.getType(fileUri); if (V) Log.v(TAG, "Got mimetype: " + contentType + " Got uri: " + fileUri); if (TextUtils.isEmpty(contentType)) { contentType = mTypeOfMultipleFiles; } - - BluetoothOppSendFileInfo fileInfo = BluetoothOppSendFileInfo.generateFileInfo( - mContext, fileUri, contentType); - ContentValues values = new ContentValues(); - values.put(BluetoothShare.URI, fileUri.toString()); values.put(BluetoothShare.MIMETYPE, contentType); values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress()); values.put(BluetoothShare.TIMESTAMP, ts); diff --git a/src/com/android/bluetooth/opp/BluetoothOppNotification.java b/src/com/android/bluetooth/opp/BluetoothOppNotification.java index 778b2f134..28e3fb909 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppNotification.java +++ b/src/com/android/bluetooth/opp/BluetoothOppNotification.java @@ -171,8 +171,8 @@ class BluetoothOppNotification { mInboundUpdateCompleteNotification = true; mOutboundUpdateCompleteNotification = true; updateCompletedNotification(); - updateIncomingFileConfirmNotification(); mPendingUpdate = 0; + cancelIncomingFileConfirmNotification(); mHandler.removeMessages(NOTIFY); } } @@ -622,4 +622,36 @@ class BluetoothOppNotification { if (V) Log.v(TAG, "Freeing cursor: " + cursor); cursor = null; } + + private void cancelIncomingFileConfirmNotification() { + Cursor cursor = null; + try { + cursor = mContext.getContentResolver().query(BluetoothShare.CONTENT_URI, null, + WHERE_CONFIRM_PENDING, null, BluetoothShare._ID); + } catch (SQLiteException e) { + if (cursor != null) { + cursor.close(); + } + cursor = null; + Log.e(TAG, "cancelupdateIncomingFileConfirmNotification: " + e); + } catch (CursorWindowAllocationException e) { + cursor = null; + Log.e(TAG, "cancelupdateIncomingFileConfirmNotification: " + e); + } + + + if (cursor == null) { + return; + } + + for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { + int id = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID)); + if (V) Log.v(TAG, "Cancelling incoming notification " + id); + + mNotificationMgr.cancel(id); + } + cursor.close(); + if (V) Log.v(TAG, "Freeing cursor: " + cursor); + cursor = null; + } } diff --git a/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java b/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java index a3b4d1181..d7c9ac683 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java +++ b/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java @@ -610,7 +610,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } finally { try { // Close InputStream and remove SendFileInfo from map - BluetoothOppUtility.closeSendFileInfo(mInfo.mUri, fileInfo); + BluetoothOppUtility.closeSendFileInfo(mInfo.mUri); if (uiUpdateThread != null) { uiUpdateThread.interrupt (); diff --git a/src/com/android/bluetooth/opp/BluetoothOppService.java b/src/com/android/bluetooth/opp/BluetoothOppService.java index e43e83a9c..8e7b836c6 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppService.java +++ b/src/com/android/bluetooth/opp/BluetoothOppService.java @@ -706,7 +706,7 @@ public class BluetoothOppService extends Service { if (sendFileInfo == null || sendFileInfo.mInputStream == null) { Log.e(TAG, "Can't open file for OUTBOUND info " + info.mId); Constants.updateShareStatus(this, info.mId, BluetoothShare.STATUS_BAD_REQUEST); - BluetoothOppUtility.closeSendFileInfo(info.mUri, sendFileInfo); + BluetoothOppUtility.closeSendFileInfo(info.mUri); return; } } diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransfer.java b/src/com/android/bluetooth/opp/BluetoothOppTransfer.java index 193cc340e..9ec562387 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppTransfer.java +++ b/src/com/android/bluetooth/opp/BluetoothOppTransfer.java @@ -351,7 +351,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch if (info.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { BluetoothOppSendFileInfo fileInfo = BluetoothOppUtility.getSendFileInfo(info.mUri); - BluetoothOppUtility.closeSendFileInfo(info.mUri, fileInfo); + BluetoothOppUtility.closeSendFileInfo(info.mUri); if (fileInfo.mFileName != null) { updateValues.put(BluetoothShare.FILENAME_HINT, fileInfo.mFileName); updateValues.put(BluetoothShare.TOTAL_BYTES, fileInfo.mLength); diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java b/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java index 7e315a59a..78f75ed58 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java +++ b/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java @@ -371,10 +371,13 @@ public class BluetoothOppTransferActivity extends AlertActivity implements .cancel(mTransInfo.mID); // retry the failed transfer + Uri uri = BluetoothOppUtility.originalUri(Uri.parse(mTransInfo.mFileUri)); + BluetoothOppSendFileInfo sendFileInfo = + BluetoothOppSendFileInfo.generateFileInfo(this, uri, mTransInfo.mFileType); + uri = BluetoothOppUtility.generateUri(uri, sendFileInfo); + BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo); + mTransInfo.mFileUri = uri.toString(); BluetoothOppUtility.retryTransfer(this, mTransInfo); - Uri uri = Uri.parse(mTransInfo.mFileUri); - BluetoothOppUtility.putSendFileInfo(uri, - BluetoothOppSendFileInfo.generateFileInfo(this, uri, mTransInfo.mFileType)); BluetoothDevice remoteDevice = mAdapter.getRemoteDevice(mTransInfo.mDestAddr); diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java b/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java index abe343f95..037c67c1d 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java +++ b/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java @@ -76,6 +76,8 @@ public class BluetoothOppTransferHistory extends Activity implements private boolean mShowAllIncoming; + private boolean mContextMenu = false; + /** Class to handle Notification Manager updates */ private BluetoothOppNotification mNotifier; @@ -182,12 +184,14 @@ public class BluetoothOppTransferHistory extends Activity implements updateNotificationWhenBtDisabled(); return true; } + mContextMenu = false; return false; } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { if (mTransferCursor != null) { + mContextMenu = true; AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo; mTransferCursor.moveToPosition(info.position); mContextMenuPosition = info.position; @@ -263,9 +267,13 @@ public class BluetoothOppTransferHistory extends Activity implements */ public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // Open the selected item - mTransferCursor.moveToPosition(position); - openCompleteTransfer(); - updateNotificationWhenBtDisabled(); + if (V) Log.v(TAG, "onItemClick: ContextMenu = " + mContextMenu); + if (!mContextMenu) { + mTransferCursor.moveToPosition(position); + openCompleteTransfer(); + updateNotificationWhenBtDisabled(); + } + mContextMenu = false; } /** diff --git a/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/src/com/android/bluetooth/opp/BluetoothOppUtility.java index 21a27d2e4..f50b0fd15 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppUtility.java +++ b/src/com/android/bluetooth/opp/BluetoothOppUtility.java @@ -112,7 +112,7 @@ public class BluetoothOppUtility { info.mFileUri = cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.URI)); if (info.mFileUri != null) { - Uri u = Uri.parse(info.mFileUri); + Uri u = originalUri(Uri.parse(info.mFileUri)); info.mFileType = context.getContentResolver().getType(u); } else { Uri u = Uri.parse(info.mFileName); @@ -336,6 +336,26 @@ public class BluetoothOppUtility { transInfo.mDeviceName); } + static Uri originalUri(Uri uri) { + String mUri = uri.toString(); + int atIndex = mUri.lastIndexOf("@"); + if (atIndex != -1) { + mUri = mUri.substring(0, atIndex); + uri = Uri.parse(mUri); + } + if (V) Log.v(TAG, "originalUri: " + uri); + return uri; + } + + static Uri generateUri(Uri uri, BluetoothOppSendFileInfo sendFileInfo) { + String fileInfo = sendFileInfo.toString(); + int atIndex = fileInfo.lastIndexOf("@"); + fileInfo = fileInfo.substring(atIndex); + uri = Uri.parse(uri + fileInfo); + if (V) Log.v(TAG, "generateUri: " + uri); + return uri; + } + static void putSendFileInfo(Uri uri, BluetoothOppSendFileInfo sendFileInfo) { if (D) Log.d(TAG, "putSendFileInfo: uri=" + uri + " sendFileInfo=" + sendFileInfo); sSendFileMap.put(uri, sendFileInfo); @@ -347,12 +367,12 @@ public class BluetoothOppUtility { return (info != null) ? info : BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR; } - static void closeSendFileInfo(Uri uri, BluetoothOppSendFileInfo sendFileInfo) { - if (D) Log.d(TAG, "closeSendFileInfo: uri=" + uri + "sendFileInfo: " + sendFileInfo); - boolean removed = sSendFileMap.remove(uri, sendFileInfo); - if (removed && sendFileInfo != null && sendFileInfo.mInputStream != null) { + static void closeSendFileInfo(Uri uri) { + if (D) Log.d(TAG, "closeSendFileInfo: uri=" + uri); + BluetoothOppSendFileInfo info = sSendFileMap.remove(uri); + if (info != null && info.mInputStream != null) { try { - sendFileInfo.mInputStream.close(); + info.mInputStream.close(); } catch (IOException ignored) { } } |