diff options
Diffstat (limited to 'car-usb-handler')
4 files changed, 96 insertions, 36 deletions
diff --git a/car-usb-handler/res/values/strings.xml b/car-usb-handler/res/values/strings.xml index 2242648941..be1e7a2332 100644 --- a/car-usb-handler/res/values/strings.xml +++ b/car-usb-handler/res/values/strings.xml @@ -26,4 +26,5 @@ <string name="usb_pref_delete_yes">Yes</string> <string name="usb_pref_delete_cancel">Cancel</string> <string name="usb_resolving_handlers">Getting supported handlers</string> + <string name="usb_unknown_device">Unknown USB device</string> </resources> diff --git a/car-usb-handler/src/android/car/usb/handler/UsbDeviceSettings.java b/car-usb-handler/src/android/car/usb/handler/UsbDeviceSettings.java index 5084414093..288f5982fe 100644 --- a/car-usb-handler/src/android/car/usb/handler/UsbDeviceSettings.java +++ b/car-usb-handler/src/android/car/usb/handler/UsbDeviceSettings.java @@ -17,7 +17,6 @@ package android.car.usb.handler; import android.content.ComponentName; import android.hardware.usb.UsbDevice; -import com.android.internal.util.Preconditions; /** * Settings for USB device. @@ -34,8 +33,6 @@ public final class UsbDeviceSettings { private boolean mDefaultHandler; UsbDeviceSettings(String serialNumber, int vid, int pid) { - Preconditions.checkNotNull(serialNumber); - mSerialNumber = serialNumber; mVid = vid; mPid = pid; @@ -96,7 +93,15 @@ public final class UsbDeviceSettings { * Checks if setting matches {@code UsbDevice}. */ public boolean matchesDevice(UsbDevice device) { - return getSerialNumber().equals(device.getSerialNumber()); + String deviceSerial = device.getSerialNumber(); + if (AoapInterface.isDeviceInAoapMode(device)) { + return mAoap && deviceSerial.equals(mSerialNumber); + } else if (deviceSerial == null) { + return mVid == device.getVendorId() && mPid == device.getProductId(); + } else { + return mVid == device.getVendorId() && mPid == device.getProductId() + && deviceSerial.equals(mSerialNumber); + } } /** diff --git a/car-usb-handler/src/android/car/usb/handler/UsbHostController.java b/car-usb-handler/src/android/car/usb/handler/UsbHostController.java index b705928fec..5c61a98091 100644 --- a/car-usb-handler/src/android/car/usb/handler/UsbHostController.java +++ b/car-usb-handler/src/android/car/usb/handler/UsbHostController.java @@ -68,10 +68,10 @@ public final class UsbHostController public void onReceive(Context context, Intent intent) { if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) { UsbDevice device = intent.<UsbDevice>getParcelableExtra(UsbManager.EXTRA_DEVICE); - unsetActiveDeviceIfSerialMatch(device); + unsetActiveDeviceIfMatch(device); } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) { UsbDevice device = intent.<UsbDevice>getParcelableExtra(UsbManager.EXTRA_DEVICE); - setActiveDeviceIfSerialMatch(device); + setActiveDeviceIfMatch(device); } } }; @@ -79,9 +79,6 @@ public final class UsbHostController @GuardedBy("this") private UsbDevice mActiveDevice; - @GuardedBy("this") - private String mProcessingDeviceSerial; - public UsbHostController(Context context, UsbHostControllerCallbacks callbacks) { mContext = context; mCallback = callbacks; @@ -96,17 +93,17 @@ public final class UsbHostController } - private synchronized void setActiveDeviceIfSerialMatch(UsbDevice device) { - if (device != null && device.getSerialNumber() != null - && device.getSerialNumber().equals(mProcessingDeviceSerial)) { + private synchronized void setActiveDeviceIfMatch(UsbDevice device) { + if (mActiveDevice != null && device != null + && UsbUtil.isDevicesMatching(device, mActiveDevice)) { mActiveDevice = device; } } - private synchronized void unsetActiveDeviceIfSerialMatch(UsbDevice device) { + private synchronized void unsetActiveDeviceIfMatch(UsbDevice device) { mHandler.requestDeviceRemoved(); - if (mActiveDevice != null && mActiveDevice.getSerialNumber() != null - && mActiveDevice.getSerialNumber().equals(device.getSerialNumber())) { + if (mActiveDevice != null && device != null + && UsbUtil.isDevicesMatching(device, mActiveDevice)) { mActiveDevice = null; } } @@ -114,7 +111,6 @@ public final class UsbHostController private synchronized boolean startDeviceProcessingIfNull(UsbDevice device) { if (mActiveDevice == null) { mActiveDevice = device; - mProcessingDeviceSerial = device.getSerialNumber(); return true; } return false; @@ -122,7 +118,6 @@ public final class UsbHostController private synchronized void stopDeviceProcessing() { mActiveDevice = null; - mProcessingDeviceSerial = null; } private synchronized UsbDevice getActiveDevice() { @@ -131,8 +126,22 @@ public final class UsbHostController private boolean deviceMatchedActiveDevice(UsbDevice device) { UsbDevice activeDevice = getActiveDevice(); - return activeDevice != null && activeDevice.getSerialNumber() != null - && activeDevice.getSerialNumber().equals(device.getSerialNumber()); + return activeDevice != null && UsbUtil.isDevicesMatching(activeDevice, device); + } + + private String generateTitle() { + String manufacturer = mActiveDevice.getManufacturerName(); + String product = mActiveDevice.getProductName(); + if (manufacturer == null && product == null) { + return mContext.getString(R.string.usb_unknown_device); + } + if (manufacturer != null && product != null) { + return manufacturer + " " + product; + } + if (manufacturer != null) { + return manufacturer; + } + return product; } /** @@ -147,7 +156,7 @@ public final class UsbHostController mCallback.optionsUpdated(mEmptyList); mCallback.processingStateChanged(true); - UsbDeviceSettings settings = mUsbSettingsStorage.getSettings(device.getSerialNumber()); + UsbDeviceSettings settings = mUsbSettingsStorage.getSettings(device); if (settings != null && mUsbResolver.dispatch( mActiveDevice, settings.getHandler(), settings.getAoap())) { if (LOCAL_LOGV) { @@ -156,7 +165,7 @@ public final class UsbHostController } return; } - mCallback.titleChanged(device.getManufacturerName() + " " + device.getProductName()); + mCallback.titleChanged(generateTitle()); mUsbResolver.resolve(device); } diff --git a/car-usb-handler/src/android/car/usb/handler/UsbSettingsStorage.java b/car-usb-handler/src/android/car/usb/handler/UsbSettingsStorage.java index 157c92f9d6..1b251f8eee 100644 --- a/car-usb-handler/src/android/car/usb/handler/UsbSettingsStorage.java +++ b/car-usb-handler/src/android/car/usb/handler/UsbSettingsStorage.java @@ -22,6 +22,7 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.hardware.usb.UsbDevice; import android.util.Log; import java.util.ArrayList; import java.util.List; @@ -47,26 +48,43 @@ public final class UsbSettingsStorage { mDbHelper = new UsbSettingsDbHelper(context); } + private Cursor queryFor(SQLiteDatabase db, UsbDevice device) { + String serial = device.getSerialNumber(); + String selection; + String[] selectionArgs; + if (AoapInterface.isDeviceInAoapMode(device)) { + selection = COLUMN_SERIAL + " = ? AND " + COLUMN_AOAP + " = 1"; + selectionArgs = new String[] {serial}; + } else if (serial == null) { + selection = COLUMN_SERIAL + " IS NULL AND " + + COLUMN_VID + " = ? AND " + COLUMN_PID + " = ?"; + selectionArgs = new String[] { + Integer.toString(device.getVendorId()), + Integer.toString(device.getProductId())}; + } else { + selection = + COLUMN_SERIAL + " = ? AND " + COLUMN_VID + " = ? AND " + COLUMN_PID + " = ?"; + selectionArgs = new String[] { + device.getSerialNumber(), + Integer.toString(device.getVendorId()), + Integer.toString(device.getProductId())}; + } + return db.query(TABLE_USB_SETTINGS, null, selection, selectionArgs, null, null, null); + } + /** * Returns settings for {@serialNumber} or null if it doesn't exist. */ @Nullable - public UsbDeviceSettings getSettings(String serialNumber) { + public UsbDeviceSettings getSettings(UsbDevice device) { try (SQLiteDatabase db = mDbHelper.getReadableDatabase(); - Cursor resultCursor = db.query( - TABLE_USB_SETTINGS, - null, - COLUMN_SERIAL + " = ?", - new String[]{serialNumber}, - null, - null, - null)) { + Cursor resultCursor = queryFor(db, device)) { if (resultCursor.getCount() > 1) { - throw new RuntimeException("Querying for serial number: " + serialNumber + throw new RuntimeException("Querying for device: " + device + " returned " + resultCursor.getCount() + " results"); } if (resultCursor.getCount() == 0) { - Log.w(TAG, "Usb setting missing for device serial: " + serialNumber); + Log.w(TAG, "Usb setting missing for device: " + device); return null; } List<UsbDeviceSettings> settings = constructSettings(resultCursor); @@ -168,7 +186,7 @@ public final class UsbSettingsStorage { private static class UsbSettingsDbHelper extends SQLiteOpenHelper { - private static final int DATABASE_VERSION = 1; + private static final int DATABASE_VERSION = 2; private static final String DATABASE_NAME = "usb_devices.db"; UsbSettingsDbHelper(Context context) { @@ -177,20 +195,47 @@ public final class UsbSettingsStorage { @Override public void onCreate(SQLiteDatabase db) { - db.execSQL("CREATE TABLE " + TABLE_USB_SETTINGS + " (" + createTable(db, TABLE_USB_SETTINGS); + createSerialIndex(db); + } + + private void createTable(SQLiteDatabase db, String tableName) { + db.execSQL("CREATE TABLE " + tableName + " (" + COLUMN_SERIAL + " TEXT," + COLUMN_VID + " INTEGER," + COLUMN_PID + " INTEGER," + COLUMN_NAME + " TEXT, " + COLUMN_HANDLER + " TEXT," + COLUMN_AOAP + " INTEGER," - + COLUMN_DEFAULT_HANDLER + " INTEGER," + "PRIMARY KEY (" + COLUMN_SERIAL + + COLUMN_DEFAULT_HANDLER + " INTEGER," + + "PRIMARY KEY (" + COLUMN_SERIAL + ", " + COLUMN_VID + ", " + COLUMN_PID + "))"); } + private void createSerialIndex(SQLiteDatabase db) { + db.execSQL("CREATE INDEX " + TABLE_USB_SETTINGS + "_" + COLUMN_SERIAL + " ON " + + TABLE_USB_SETTINGS + "(" + COLUMN_SERIAL + ")"); + } + @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - // Do nothing at this point. Not required for v1 database. + for (; oldVersion != newVersion; oldVersion++) { + switch (oldVersion) { + case 1: + String tempTableName = "temp_" + TABLE_USB_SETTINGS; + createTable(db, tempTableName); + db.execSQL("INSERT INTO " + tempTableName + + " SELECT * FROM " + TABLE_USB_SETTINGS); + db.execSQL("DROP TABLE " + TABLE_USB_SETTINGS); + db.execSQL("ALTER TABLE " + tempTableName + " RENAME TO " + + TABLE_USB_SETTINGS); + createSerialIndex(db); + break; + default: + throw new IllegalArgumentException( + "Unknown database version " + oldVersion); + } + } } } } |