Merge "Move Bluetooth off the product="..." strings xml feature"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 846e0ab..1389e0d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -178,9 +178,9 @@
     <string name="bt_toast_6">Stopped sending file to \u0022<xliff:g id="recipient">%1$s</xliff:g>\u0022</string>
 
     <!-- Bluetooth System Messages [CHAR LIMIT=NONE] -->
-    <string name="bt_sm_2_1" product="nosdcard">There isn\'t enough space in USB storage to save the file from \u0022<xliff:g id="sender">%1$s</xliff:g>\u0022</string>
+    <string name="bt_sm_2_1_nosdcard">There isn\'t enough space in USB storage to save the file from \u0022<xliff:g id="sender">%1$s</xliff:g>\u0022</string>
     <!-- Bluetooth System Messages -->
-    <string name="bt_sm_2_1" product="default">There isn\'t enough space on the SD card to save the file from \u0022<xliff:g id="sender">%1$s</xliff:g>\u0022</string>
+    <string name="bt_sm_2_1_default">There isn\'t enough space on the SD card to save the file from \u0022<xliff:g id="sender">%1$s</xliff:g>\u0022</string>
     <string name="bt_sm_2_2">Space needed: <xliff:g id="size">%1$s</xliff:g></string>
 
     <string name="ErrorTooManyRequests">Too many requests are being processed. Try again later.</string>
@@ -194,8 +194,8 @@
     <string name="status_canceled">Transfer canceled by user.</string>
     <string name="status_file_error">Storage issue.</string>
     <!-- Shown when USB storage cannot be found.  [CHAR LIMIT=NONE] -->
-    <string name="status_no_sd_card" product="nosdcard">No USB storage.</string>
-    <string name="status_no_sd_card" product="default">No SD card. Insert an SD card to save transferred files.</string>
+    <string name="status_no_sd_card_nosdcard">No USB storage.</string>
+    <string name="status_no_sd_card_default">No SD card. Insert an SD card to save transferred files.</string>
     <string name="status_connection_error">Connection unsuccessful.</string>
     <string name="status_protocol_error">Request can\'t be handled correctly.</string>
     <string name="status_unknown_error">Unknown error.</string>
diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java b/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java
index 74fd872..fc45d3f 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java
@@ -309,7 +309,10 @@
         } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL) {
             if (mTransInfo.mStatus == BluetoothShare.STATUS_ERROR_SDCARD_FULL) {
                 mLine1View = (TextView) mView.findViewById(R.id.line1_view);
-                tmp = getString(R.string.bt_sm_2_1, mTransInfo.mDeviceName);
+                int id = BluetoothOppUtility.deviceHasNoSdCard()
+                        ? R.string.bt_sm_2_1_nosdcard
+                        : R.string.bt_sm_2_1_default;
+                tmp = getString(id);
                 mLine1View.setText(tmp);
                 mLine2View = (TextView) mView.findViewById(R.id.line2_view);
                 tmp = getString(R.string.download_fail_line2, mTransInfo.mFileName);
diff --git a/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/src/com/android/bluetooth/opp/BluetoothOppUtility.java
index 1b5cd59..7533d0d 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppUtility.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppUtility.java
@@ -45,6 +45,7 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Environment;
+import android.os.SystemProperties;
 import android.util.Log;
 
 import com.android.bluetooth.R;
@@ -56,6 +57,7 @@
 import java.math.RoundingMode;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -66,6 +68,8 @@
     private static final String TAG = "BluetoothOppUtility";
     private static final boolean D = Constants.DEBUG;
     private static final boolean V = Constants.VERBOSE;
+    /** Whether the device has the "nosdcard" characteristic, or null if not-yet-known. */
+    private static Boolean sNoSdCard = null;
 
     private static final ConcurrentHashMap<Uri, BluetoothOppSendFileInfo> sSendFileMap =
             new ConcurrentHashMap<Uri, BluetoothOppSendFileInfo>();
@@ -292,6 +296,17 @@
     }
 
     /**
+     * Whether the device has the "nosdcard" characteristic or not.
+     */
+    public static boolean deviceHasNoSdCard() {
+        if (sNoSdCard == null) {
+            String characteristics = SystemProperties.get("ro.build.characteristics", "");
+            sNoSdCard = Arrays.asList(characteristics).contains("nosdcard");
+        }
+        return sNoSdCard;
+    }
+
+    /**
      * Get status description according to status code.
      */
     public static String getStatusDescription(Context context, int statusCode, String deviceName) {
@@ -311,11 +326,15 @@
         } else if (statusCode == BluetoothShare.STATUS_FILE_ERROR) {
             ret = context.getString(R.string.status_file_error);
         } else if (statusCode == BluetoothShare.STATUS_ERROR_NO_SDCARD) {
-            ret = context.getString(R.string.status_no_sd_card);
+            int id = deviceHasNoSdCard()
+                    ? R.string.status_no_sd_card_nosdcard
+                    : R.string.status_no_sd_card_default;
+            ret = context.getString(id);
         } else if (statusCode == BluetoothShare.STATUS_CONNECTION_ERROR) {
             ret = context.getString(R.string.status_connection_error);
         } else if (statusCode == BluetoothShare.STATUS_ERROR_SDCARD_FULL) {
-            ret = context.getString(R.string.bt_sm_2_1, deviceName);
+            int id = deviceHasNoSdCard() ? R.string.bt_sm_2_1_nosdcard : R.string.bt_sm_2_1_default;
+            ret = context.getString(id);
         } else if ((statusCode == BluetoothShare.STATUS_BAD_REQUEST) || (statusCode
                 == BluetoothShare.STATUS_LENGTH_REQUIRED) || (statusCode
                 == BluetoothShare.STATUS_PRECONDITION_FAILED) || (statusCode