Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 630fc40a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Don't show "always use" when app can't be default"

parents 3f89bd67 5a633c6e
Loading
Loading
Loading
Loading
+145 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017 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 android.hardware.usb;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.util.Objects;

/**
 * This class is used to describe a USB accessory.
 * When used in HashMaps all values must be specified,
 * but wildcards can be used for any of the fields in
 * the package meta-data.
 *
 * @hide
 */
public class AccessoryFilter {
    // USB accessory manufacturer (or null for unspecified)
    public final String mManufacturer;
    // USB accessory model (or null for unspecified)
    public final String mModel;
    // USB accessory version (or null for unspecified)
    public final String mVersion;

    public AccessoryFilter(String manufacturer, String model, String version) {
        mManufacturer = manufacturer;
        mModel = model;
        mVersion = version;
    }

    public AccessoryFilter(UsbAccessory accessory) {
        mManufacturer = accessory.getManufacturer();
        mModel = accessory.getModel();
        mVersion = accessory.getVersion();
    }

    public static AccessoryFilter read(XmlPullParser parser)
            throws XmlPullParserException, IOException {
        String manufacturer = null;
        String model = null;
        String version = null;

        int count = parser.getAttributeCount();
        for (int i = 0; i < count; i++) {
            String name = parser.getAttributeName(i);
            String value = parser.getAttributeValue(i);

            if ("manufacturer".equals(name)) {
                manufacturer = value;
            } else if ("model".equals(name)) {
                model = value;
            } else if ("version".equals(name)) {
                version = value;
            }
        }
        return new AccessoryFilter(manufacturer, model, version);
    }

    public void write(XmlSerializer serializer)throws IOException {
        serializer.startTag(null, "usb-accessory");
        if (mManufacturer != null) {
            serializer.attribute(null, "manufacturer", mManufacturer);
        }
        if (mModel != null) {
            serializer.attribute(null, "model", mModel);
        }
        if (mVersion != null) {
            serializer.attribute(null, "version", mVersion);
        }
        serializer.endTag(null, "usb-accessory");
    }

    public boolean matches(UsbAccessory acc) {
        if (mManufacturer != null && !acc.getManufacturer().equals(mManufacturer)) return false;
        if (mModel != null && !acc.getModel().equals(mModel)) return false;
        return !(mVersion != null && !acc.getVersion().equals(mVersion));
    }

    /**
     * Is the accessories described {@code accessory} covered by this filter?
     *
     * @param accessory A filter describing the accessory
     *
     * @return {@code true} iff this the filter covers the accessory
     */
    public boolean contains(AccessoryFilter accessory) {
        if (mManufacturer != null && !Objects.equals(accessory.mManufacturer, mManufacturer)) {
            return false;
        }
        if (mModel != null && !Objects.equals(accessory.mModel, mModel)) return false;
        return !(mVersion != null && !Objects.equals(accessory.mVersion, mVersion));
    }

    @Override
    public boolean equals(Object obj) {
        // can't compare if we have wildcard strings
        if (mManufacturer == null || mModel == null || mVersion == null) {
            return false;
        }
        if (obj instanceof AccessoryFilter) {
            AccessoryFilter filter = (AccessoryFilter)obj;
            return (mManufacturer.equals(filter.mManufacturer) &&
                    mModel.equals(filter.mModel) &&
                    mVersion.equals(filter.mVersion));
        }
        if (obj instanceof UsbAccessory) {
            UsbAccessory accessory = (UsbAccessory)obj;
            return (mManufacturer.equals(accessory.getManufacturer()) &&
                    mModel.equals(accessory.getModel()) &&
                    mVersion.equals(accessory.getVersion()));
        }
        return false;
    }

    @Override
    public int hashCode() {
        return ((mManufacturer == null ? 0 : mManufacturer.hashCode()) ^
                (mModel == null ? 0 : mModel.hashCode()) ^
                (mVersion == null ? 0 : mVersion.hashCode()));
    }

    @Override
    public String toString() {
        return "AccessoryFilter[mManufacturer=\"" + mManufacturer +
                "\", mModel=\"" + mModel +
                "\", mVersion=\"" + mVersion + "\"]";
    }
}
+313 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017 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 android.hardware.usb;

import android.util.Slog;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.util.Objects;

/**
 * This class is used to describe a USB device.
 * When used in HashMaps all values must be specified,
 * but wildcards can be used for any of the fields in
 * the package meta-data.
 *
 * @hide
 */
public class DeviceFilter {
    private static final String TAG = DeviceFilter.class.getSimpleName();

    // USB Vendor ID (or -1 for unspecified)
    public final int mVendorId;
    // USB Product ID (or -1 for unspecified)
    public final int mProductId;
    // USB device or interface class (or -1 for unspecified)
    public final int mClass;
    // USB device subclass (or -1 for unspecified)
    public final int mSubclass;
    // USB device protocol (or -1 for unspecified)
    public final int mProtocol;
    // USB device manufacturer name string (or null for unspecified)
    public final String mManufacturerName;
    // USB device product name string (or null for unspecified)
    public final String mProductName;
    // USB device serial number string (or null for unspecified)
    public final String mSerialNumber;

    public DeviceFilter(int vid, int pid, int clasz, int subclass, int protocol,
            String manufacturer, String product, String serialnum) {
        mVendorId = vid;
        mProductId = pid;
        mClass = clasz;
        mSubclass = subclass;
        mProtocol = protocol;
        mManufacturerName = manufacturer;
        mProductName = product;
        mSerialNumber = serialnum;
    }

    public DeviceFilter(UsbDevice device) {
        mVendorId = device.getVendorId();
        mProductId = device.getProductId();
        mClass = device.getDeviceClass();
        mSubclass = device.getDeviceSubclass();
        mProtocol = device.getDeviceProtocol();
        mManufacturerName = device.getManufacturerName();
        mProductName = device.getProductName();
        mSerialNumber = device.getSerialNumber();
    }

    public static DeviceFilter read(XmlPullParser parser)
            throws XmlPullParserException, IOException {
        int vendorId = -1;
        int productId = -1;
        int deviceClass = -1;
        int deviceSubclass = -1;
        int deviceProtocol = -1;
        String manufacturerName = null;
        String productName = null;
        String serialNumber = null;

        int count = parser.getAttributeCount();
        for (int i = 0; i < count; i++) {
            String name = parser.getAttributeName(i);
            String value = parser.getAttributeValue(i);
            // Attribute values are ints or strings
            if ("manufacturer-name".equals(name)) {
                manufacturerName = value;
            } else if ("product-name".equals(name)) {
                productName = value;
            } else if ("serial-number".equals(name)) {
                serialNumber = value;
            } else {
                int intValue;
                int radix = 10;
                if (value != null && value.length() > 2 && value.charAt(0) == '0' &&
                        (value.charAt(1) == 'x' || value.charAt(1) == 'X')) {
                    // allow hex values starting with 0x or 0X
                    radix = 16;
                    value = value.substring(2);
                }
                try {
                    intValue = Integer.parseInt(value, radix);
                } catch (NumberFormatException e) {
                    Slog.e(TAG, "invalid number for field " + name, e);
                    continue;
                }
                if ("vendor-id".equals(name)) {
                    vendorId = intValue;
                } else if ("product-id".equals(name)) {
                    productId = intValue;
                } else if ("class".equals(name)) {
                    deviceClass = intValue;
                } else if ("subclass".equals(name)) {
                    deviceSubclass = intValue;
                } else if ("protocol".equals(name)) {
                    deviceProtocol = intValue;
                }
            }
        }
        return new DeviceFilter(vendorId, productId,
                deviceClass, deviceSubclass, deviceProtocol,
                manufacturerName, productName, serialNumber);
    }

    public void write(XmlSerializer serializer) throws IOException {
        serializer.startTag(null, "usb-device");
        if (mVendorId != -1) {
            serializer.attribute(null, "vendor-id", Integer.toString(mVendorId));
        }
        if (mProductId != -1) {
            serializer.attribute(null, "product-id", Integer.toString(mProductId));
        }
        if (mClass != -1) {
            serializer.attribute(null, "class", Integer.toString(mClass));
        }
        if (mSubclass != -1) {
            serializer.attribute(null, "subclass", Integer.toString(mSubclass));
        }
        if (mProtocol != -1) {
            serializer.attribute(null, "protocol", Integer.toString(mProtocol));
        }
        if (mManufacturerName != null) {
            serializer.attribute(null, "manufacturer-name", mManufacturerName);
        }
        if (mProductName != null) {
            serializer.attribute(null, "product-name", mProductName);
        }
        if (mSerialNumber != null) {
            serializer.attribute(null, "serial-number", mSerialNumber);
        }
        serializer.endTag(null, "usb-device");
    }

    private boolean matches(int clasz, int subclass, int protocol) {
        return ((mClass == -1 || clasz == mClass) &&
                (mSubclass == -1 || subclass == mSubclass) &&
                (mProtocol == -1 || protocol == mProtocol));
    }

    public boolean matches(UsbDevice device) {
        if (mVendorId != -1 && device.getVendorId() != mVendorId) return false;
        if (mProductId != -1 && device.getProductId() != mProductId) return false;
        if (mManufacturerName != null && device.getManufacturerName() == null) return false;
        if (mProductName != null && device.getProductName() == null) return false;
        if (mSerialNumber != null && device.getSerialNumber() == null) return false;
        if (mManufacturerName != null && device.getManufacturerName() != null &&
                !mManufacturerName.equals(device.getManufacturerName())) return false;
        if (mProductName != null && device.getProductName() != null &&
                !mProductName.equals(device.getProductName())) return false;
        if (mSerialNumber != null && device.getSerialNumber() != null &&
                !mSerialNumber.equals(device.getSerialNumber())) return false;

        // check device class/subclass/protocol
        if (matches(device.getDeviceClass(), device.getDeviceSubclass(),
                device.getDeviceProtocol())) return true;

        // if device doesn't match, check the interfaces
        int count = device.getInterfaceCount();
        for (int i = 0; i < count; i++) {
            UsbInterface intf = device.getInterface(i);
            if (matches(intf.getInterfaceClass(), intf.getInterfaceSubclass(),
                    intf.getInterfaceProtocol())) return true;
        }

        return false;
    }

    /**
     * If the device described by {@code device} covered by this filter?
     *
     * @param device The device
     *
     * @return {@code true} iff this filter covers the {@code device}
     */
    public boolean contains(DeviceFilter device) {
        // -1 and null means "match anything"

        if (mVendorId != -1 && device.mVendorId != mVendorId) return false;
        if (mProductId != -1 && device.mProductId != mProductId) return false;
        if (mManufacturerName != null && !Objects.equals(mManufacturerName,
                device.mManufacturerName)) {
            return false;
        }
        if (mProductName != null && !Objects.equals(mProductName, device.mProductName)) {
            return false;
        }
        if (mSerialNumber != null
                && !Objects.equals(mSerialNumber, device.mSerialNumber)) {
            return false;
        }

        // check device class/subclass/protocol
        return matches(device.mClass, device.mSubclass, device.mProtocol);
    }

    @Override
    public boolean equals(Object obj) {
        // can't compare if we have wildcard strings
        if (mVendorId == -1 || mProductId == -1 ||
                mClass == -1 || mSubclass == -1 || mProtocol == -1) {
            return false;
        }
        if (obj instanceof DeviceFilter) {
            DeviceFilter filter = (DeviceFilter)obj;

            if (filter.mVendorId != mVendorId ||
                    filter.mProductId != mProductId ||
                    filter.mClass != mClass ||
                    filter.mSubclass != mSubclass ||
                    filter.mProtocol != mProtocol) {
                return(false);
            }
            if ((filter.mManufacturerName != null &&
                    mManufacturerName == null) ||
                    (filter.mManufacturerName == null &&
                            mManufacturerName != null) ||
                    (filter.mProductName != null &&
                            mProductName == null)  ||
                    (filter.mProductName == null &&
                            mProductName != null) ||
                    (filter.mSerialNumber != null &&
                            mSerialNumber == null)  ||
                    (filter.mSerialNumber == null &&
                            mSerialNumber != null)) {
                return(false);
            }
            if  ((filter.mManufacturerName != null &&
                    mManufacturerName != null &&
                    !mManufacturerName.equals(filter.mManufacturerName)) ||
                    (filter.mProductName != null &&
                            mProductName != null &&
                            !mProductName.equals(filter.mProductName)) ||
                    (filter.mSerialNumber != null &&
                            mSerialNumber != null &&
                            !mSerialNumber.equals(filter.mSerialNumber))) {
                return false;
            }
            return true;
        }
        if (obj instanceof UsbDevice) {
            UsbDevice device = (UsbDevice)obj;
            if (device.getVendorId() != mVendorId ||
                    device.getProductId() != mProductId ||
                    device.getDeviceClass() != mClass ||
                    device.getDeviceSubclass() != mSubclass ||
                    device.getDeviceProtocol() != mProtocol) {
                return(false);
            }
            if ((mManufacturerName != null && device.getManufacturerName() == null) ||
                    (mManufacturerName == null && device.getManufacturerName() != null) ||
                    (mProductName != null && device.getProductName() == null) ||
                    (mProductName == null && device.getProductName() != null) ||
                    (mSerialNumber != null && device.getSerialNumber() == null) ||
                    (mSerialNumber == null && device.getSerialNumber() != null)) {
                return(false);
            }
            if ((device.getManufacturerName() != null &&
                    !mManufacturerName.equals(device.getManufacturerName())) ||
                    (device.getProductName() != null &&
                            !mProductName.equals(device.getProductName())) ||
                    (device.getSerialNumber() != null &&
                            !mSerialNumber.equals(device.getSerialNumber()))) {
                return false;
            }
            return true;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return (((mVendorId << 16) | mProductId) ^
                ((mClass << 16) | (mSubclass << 8) | mProtocol));
    }

    @Override
    public String toString() {
        return "DeviceFilter[mVendorId=" + mVendorId + ",mProductId=" + mProductId +
                ",mClass=" + mClass + ",mSubclass=" + mSubclass +
                ",mProtocol=" + mProtocol + ",mManufacturerName=" + mManufacturerName +
                ",mProductName=" + mProductName + ",mSerialNumber=" + mSerialNumber +
                "]";
    }
}
+7 −7
Original line number Diff line number Diff line
@@ -124,16 +124,16 @@
    <string name="status_bar_use_physical_keyboard">Physical keyboard</string>

    <!-- Prompt for the USB device permission dialog [CHAR LIMIT=80] -->
    <string name="usb_device_permission_prompt">Allow the app <xliff:g id="application">%1$s</xliff:g> to access the USB device?</string>
    <string name="usb_device_permission_prompt">Allow <xliff:g id="application">%1$s</xliff:g> to access <xliff:g id="usb_device">%2$s</xliff:g>?</string>

    <!-- Prompt for the USB accessory permission dialog [CHAR LIMIT=80] -->
    <string name="usb_accessory_permission_prompt">Allow the app <xliff:g id="application">%1$s</xliff:g> to access the USB accessory?</string>
    <string name="usb_accessory_permission_prompt">Allow <xliff:g id="application">%1$s</xliff:g> to access <xliff:g id="usb_accessory">%2$s</xliff:g>?</string>

    <!-- Prompt for the USB device confirm dialog [CHAR LIMIT=80] -->
    <string name="usb_device_confirm_prompt">Open <xliff:g id="activity">%1$s</xliff:g> when this USB device is connected?</string>
    <string name="usb_device_confirm_prompt">Open <xliff:g id="application">%1$s</xliff:g> to handle <xliff:g id="usb_device">%2$s</xliff:g>?</string>

    <!-- Prompt for the USB accessory confirm dialog [CHAR LIMIT=80] -->
    <string name="usb_accessory_confirm_prompt">Open <xliff:g id="activity">%1$s</xliff:g> when this USB accessory is connected?</string>
    <string name="usb_accessory_confirm_prompt">Open <xliff:g id="application">%1$s</xliff:g> to handle <xliff:g id="usb_accessory">%2$s</xliff:g>?</string>

    <!-- Prompt for the USB accessory URI dialog [CHAR LIMIT=80] -->
    <string name="usb_accessory_uri_prompt">No installed apps work with this USB accessory. Learn more about this accessory at <xliff:g id="url">%1$s</xliff:g></string>
@@ -145,10 +145,10 @@
    <string name="label_view">View</string>

    <!-- Checkbox label for USB device dialogs.  [CHAR LIMIT=50] -->
    <string name="always_use_device">Use by default for this USB device</string>
    <string name="always_use_device">Always open <xliff:g id="application">%1$s</xliff:g> when <xliff:g id="usb_device">%2$s</xliff:g> is connected</string>

    <!-- Checkbox label for USB accessory dialogs.  [CHAR LIMIT=50]-->
    <string name="always_use_accessory">Use by default for this USB accessory</string>
    <string name="always_use_accessory">Always open <xliff:g id="application">%1$s</xliff:g> when <xliff:g id="usb_accessory">%2$s</xliff:g> is connected</string>

    <!-- Title of confirmation dialog for USB debugging -->
    <string name="usb_debugging_title">Allow USB debugging?</string>
+8 −4
Original line number Diff line number Diff line
@@ -71,10 +71,12 @@ public class UsbConfirmActivity extends AlertActivity
        ap.mIcon = mResolveInfo.loadIcon(packageManager);
        ap.mTitle = appName;
        if (mDevice == null) {
            ap.mMessage = getString(R.string.usb_accessory_confirm_prompt, appName);
            ap.mMessage = getString(R.string.usb_accessory_confirm_prompt, appName,
                    mAccessory.getDescription());
            mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
        } else {
            ap.mMessage = getString(R.string.usb_device_confirm_prompt, appName);
            ap.mMessage = getString(R.string.usb_device_confirm_prompt, appName,
                    mDevice.getProductName());
            mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
        }
        ap.mPositiveButtonText = getString(android.R.string.ok);
@@ -88,9 +90,11 @@ public class UsbConfirmActivity extends AlertActivity
        ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
        mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
        if (mDevice == null) {
            mAlwaysUse.setText(R.string.always_use_accessory);
            mAlwaysUse.setText(getString(R.string.always_use_accessory, appName,
                    mAccessory.getDescription()));
        } else {
            mAlwaysUse.setText(R.string.always_use_device);
            mAlwaysUse.setText(getString(R.string.always_use_device, appName,
                    mDevice.getProductName()));
        }
        mAlwaysUse.setOnCheckedChangeListener(this);
        mClearDefaultHint = (TextView)ap.mView.findViewById(
+124 −15

File changed.

Preview size limit exceeded, changes collapsed.

Loading