// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser; import android.app.Activity; import android.text.SpannableString; import android.text.TextUtils; import android.view.View; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.R; import org.chromium.chrome.browser.omnibox.OmniboxUrlEmphasizer; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.text.NoUnderlineClickableSpan; import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier.SpanInfo; /** * A dialog for showing available USB devices. This dialog is shown when a website requests to * connect to a USB device (e.g. through a usb.requestDevice Javascript call). */ public class UsbChooserDialog implements ItemChooserDialog.ItemSelectedCallback { /** * The dialog to show to let the user pick a device. */ ItemChooserDialog mItemChooserDialog; /** * A pointer back to the native part of the implementation for this dialog. */ long mNativeUsbChooserDialogPtr; /** * Creates the UsbChooserDialog. */ @VisibleForTesting UsbChooserDialog(long nativeUsbChooserDialogPtr) { mNativeUsbChooserDialogPtr = nativeUsbChooserDialogPtr; } /** * Shows the UsbChooserDialog. * * @param activity Activity which is used for launching a dialog. * @param origin The origin for the site wanting to connect to the USB device. * @param securityLevel The security level of the connection to the site wanting to connect to * the USB device. For valid values see SecurityStateModel::SecurityLevel. */ @VisibleForTesting void show(Activity activity, String origin, int securityLevel) { // Emphasize the origin. Profile profile = Profile.getLastUsedProfile(); SpannableString originSpannableString = new SpannableString(origin); OmniboxUrlEmphasizer.emphasizeUrl(originSpannableString, activity.getResources(), profile, securityLevel, false /* isInternalPage */, true /* useDarkColors */, true /* emphasizeHttpsScheme */); // Construct a full string and replace the origin text with emphasized version. SpannableString title = new SpannableString(activity.getString(R.string.usb_chooser_dialog_prompt, origin)); int start = title.toString().indexOf(origin); TextUtils.copySpansFrom(originSpannableString, 0, originSpannableString.length(), Object.class, title, start); String searching = ""; String noneFound = activity.getString(R.string.usb_chooser_dialog_no_devices_found_prompt); SpannableString statusActive = SpanApplier.applySpans( activity.getString(R.string.usb_chooser_dialog_footnote_text), new SpanInfo("<link>", "</link>", new NoUnderlineClickableSpan() { @Override public void onClick(View view) { if (mNativeUsbChooserDialogPtr == 0) { return; } nativeLoadUsbHelpPage(mNativeUsbChooserDialogPtr); // Get rid of the highlight background on selection. view.invalidate(); } })); SpannableString statusIdleNoneFound = statusActive; SpannableString statusIdleSomeFound = statusActive; String positiveButton = activity.getString(R.string.usb_chooser_dialog_connect_button_text); ItemChooserDialog.ItemChooserLabels labels = new ItemChooserDialog.ItemChooserLabels(title, searching, noneFound, statusActive, statusIdleNoneFound, statusIdleSomeFound, positiveButton); mItemChooserDialog = new ItemChooserDialog(activity, this, labels); } @Override public void onItemSelected(String id) { if (mNativeUsbChooserDialogPtr != 0) { if (id.isEmpty()) { nativeOnDialogCancelled(mNativeUsbChooserDialogPtr); } else { nativeOnItemSelected(mNativeUsbChooserDialogPtr, id); } } } @CalledByNative private static UsbChooserDialog create(WindowAndroid windowAndroid, String origin, int securityLevel, long nativeUsbChooserDialogPtr) { Activity activity = windowAndroid.getActivity().get(); if (activity == null) { return null; } UsbChooserDialog dialog = new UsbChooserDialog(nativeUsbChooserDialogPtr); dialog.show(activity, origin, securityLevel); return dialog; } @CalledByNative private void setIdleState() { mItemChooserDialog.setIdleState(); } @VisibleForTesting @CalledByNative void addDevice(String deviceId, String deviceName) { mItemChooserDialog.addOrUpdateItem( new ItemChooserDialog.ItemChooserRow(deviceId, deviceName)); } @CalledByNative private void removeDevice(String deviceId, String deviceName) { mItemChooserDialog.removeItemFromList( new ItemChooserDialog.ItemChooserRow(deviceId, deviceName)); } @CalledByNative private void closeDialog() { mNativeUsbChooserDialogPtr = 0; mItemChooserDialog.dismiss(); } @VisibleForTesting native void nativeOnItemSelected(long nativeUsbChooserDialogAndroid, String deviceId); @VisibleForTesting native void nativeOnDialogCancelled(long nativeUsbChooserDialogAndroid); @VisibleForTesting native void nativeLoadUsbHelpPage(long nativeUsbChooserDialogAndroid); }