From 4e5355aa22057c3ab11e191537af6f56c8a3ae58 Mon Sep 17 00:00:00 2001 From: ugo_yu Date: Fri, 27 May 2016 20:11:08 +0800 Subject: Mercedes Benz MAP message listing workaround Use case: Sync MAP message to Benz NTG 4.5 Precondition: 1. One of SMS message contains any special characters not ASCII Steps: 1. Connect with Benz NTG 4.5. 2. Sync SMS message from carkit. Failure: Carkit always shows "No Message". Root Cause: When this carkit requests the message listing, and any message subject has non-ASCII special characters in it, the carkit will stop all MAP activity and stay idle. Fix: Strip special characters in the subject tline in message listing for this carkit. This change also introduces a Java bases interop database for future use/expansion. Bug: 29025011 Change-Id: I4255cbeb068c82f32a68b1022285dfa723e199ec --- .../map/BluetoothMapMessageListingElement.java | 9 +++ .../android/bluetooth/map/BluetoothMapService.java | 4 +- src/com/android/bluetooth/util/Interop.java | 87 ++++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 src/com/android/bluetooth/util/Interop.java diff --git a/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java b/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java index 2d234d597..13b164ba0 100644 --- a/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java +++ b/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java @@ -27,6 +27,7 @@ import android.util.Log; import android.util.Xml; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; +import com.android.bluetooth.util.Interop; public class BluetoothMapMessageListingElement implements Comparable { @@ -277,9 +278,17 @@ public class BluetoothMapMessageListingElement BluetoothMapUtils.getMapHandle(mCpHandle, mType)); if(mSubject != null){ String stripped = BluetoothMapUtils.stripInvalidChars(mSubject); + + if (Interop.matchByAddress(Interop.INTEROP_MAP_ASCIIONLY, + BluetoothMapService.getRemoteDevice().getAddress())) { + stripped = stripped.replaceAll("[\\P{ASCII}&\"><]", ""); + if (stripped.isEmpty()) stripped = "---"; + } + xmlMsgElement.attribute(null, "subject", stripped.substring(0, stripped.length() < 256 ? stripped.length() : 256)); } + if(mDateTime != 0) xmlMsgElement.attribute(null, "datetime", this.getDateTimeString()); if(mSenderName != null) diff --git a/src/com/android/bluetooth/map/BluetoothMapService.java b/src/com/android/bluetooth/map/BluetoothMapService.java index de82c34ab..d088f0edd 100644 --- a/src/com/android/bluetooth/map/BluetoothMapService.java +++ b/src/com/android/bluetooth/map/BluetoothMapService.java @@ -133,7 +133,7 @@ public class BluetoothMapService extends ProfileService { private HashMap mMasInstanceMap = new HashMap(1); - private BluetoothDevice mRemoteDevice = null; // The remote connected device - protect access + private static BluetoothDevice mRemoteDevice = null; // The remote connected device - protect access private ArrayList mEnabledAccounts = null; private static String sRemoteDeviceName = null; @@ -476,7 +476,7 @@ public class BluetoothMapService extends ProfileService { protected boolean isMapStarted() { return !mStartError; } - public BluetoothDevice getRemoteDevice() { + public static BluetoothDevice getRemoteDevice() { return mRemoteDevice; } private void setState(int state) { diff --git a/src/com/android/bluetooth/util/Interop.java b/src/com/android/bluetooth/util/Interop.java new file mode 100644 index 000000000..4861c154e --- /dev/null +++ b/src/com/android/bluetooth/util/Interop.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.bluetooth.util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Centralized Bluetooth Interoperability workaround utilities and database. + * This is the Java version. An analagous native version can be found + * in /system/bt/devices/include/interop_database.h. + */ +public class Interop { + + /** + * Simple interop entry consisting of a workarond id (see below) + * and a (partial or complete) Bluetooth device address string + * to match against. + */ + private static class Entry { + String address; + int workaround_id; + + public Entry(int workaround_id, String address) { + this.workaround_id = workaround_id; + this.address = address; + } + } + + /** + * The actual "database" of interop entries. + */ + private static List entries = null; + + /** + * Workaround ID for deivces which do not accept non-ASCII + * characters in SMS messages. + */ + public static final int INTEROP_MAP_ASCIIONLY = 1; + + /** + * Initializes the interop datbase with the relevant workaround + * entries. + * When adding entries, please provide a description for each + * device as to what problem the workaround addresses. + */ + private static void lazyInitInteropDatabase() { + if (entries != null) return; + entries = new ArrayList(); + + /** Mercedes Benz NTG 4.5 does not handle non-ASCII characters in SMS */ + entries.add(new Entry(INTEROP_MAP_ASCIIONLY, "00:26:e8")); + } + + /** + * Checks wheter a given device identified by |address| is a match + * for a given workaround identified by |workaround_id|. + * Return true if the address matches, false otherwise. + */ + public static boolean matchByAddress(int workaround_id, String address) { + if (address == null || address.isEmpty()) return false; + + lazyInitInteropDatabase(); + for (Entry entry : entries) { + if (entry.workaround_id == workaround_id && + entry.address.startsWith(address.toLowerCase())) { + return true; + } + } + + return false; + } +} -- cgit v1.2.3