Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f8167c70a0f68a36b121d4e762950b7a8b92b647 |
| --- /dev/null |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java |
| @@ -0,0 +1,236 @@ |
| +// Copyright 2015 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.content.Context; |
| +import android.content.Intent; |
| +import android.graphics.Color; |
| +import android.text.SpannableString; |
| +import android.text.TextPaint; |
| +import android.text.TextUtils; |
| +import android.text.style.ClickableSpan; |
| +import android.view.View; |
| +import android.widget.Toast; |
| + |
| +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.SpanApplier; |
| +import org.chromium.ui.text.SpanApplier.SpanInfo; |
| + |
| +import java.util.ArrayList; |
| +import java.util.List; |
| + |
| +/** |
| + * A dialog for picking available Bluetooth devices. |
| + */ |
| +public class BluetoothChooserDialog implements ItemChooserDialog.ItemSelectedCallback { |
| + Context mContext; |
| + |
| + // The dialog to show to let the user pick a device. |
| + ItemChooserDialog mItemChooserDialog; |
| + |
| + // The origin for the site wanting to pair with the bluetooth devices. |
| + String mOrigin; |
| + |
| + // The security level of the connection to the site wanting to pair with the |
| + // bluetooth devices. |
| + int mSecurityLevel; |
| + |
| + // A pointer back to the native part of the implementation for this dialog. |
| + long mNativeBluetoothChooserDialogPtr; |
| + |
| + // The type of link that is shown within the dialog. |
| + private enum LinkType { |
| + EXPLAIN_BLUETOOTH, |
| + EXPLAIN_PARING, |
| + ADAPTER_OFF, |
| + ADAPTER_OFF_HELP, |
| + RESTART_SEARCH, |
| + } |
| + |
| + /** |
| + * Creates the BluetoothChooserDialog and displays it (and starts waiting for data). |
| + * |
| + * @param context Context which is used for launching a dialog. |
| + */ |
| + public BluetoothChooserDialog(Context context, String origin, |
| + int securityLevel, long nativeBluetoothChooserDialogPtr) { |
| + mContext = context; |
| + mOrigin = origin; |
| + mSecurityLevel = securityLevel; |
| + mNativeBluetoothChooserDialogPtr = nativeBluetoothChooserDialogPtr; |
| + } |
| + |
| + /** |
| + * Show the BluetoothChooserDialog. |
| + */ |
| + public void show() { |
| + // Emphasize the origin. |
| + Profile profile = Profile.getLastUsedProfile(); |
| + SpannableString origin = new SpannableString(mOrigin); |
| + OmniboxUrlEmphasizer.emphasizeUrl(origin, mContext.getResources(), |
| + profile, mSecurityLevel, false, true, true); |
| + // Construct a full string and replace the origin text with emphasized version. |
| + String message = mContext.getString(R.string.bluetooth_dialog_title, mOrigin); |
| + SpannableString title = SpanApplier.applySpans( |
| + message, new SpanInfo("<link>", "</link>", |
| + new NoUnderlineClickableSpan(LinkType.EXPLAIN_PARING, mContext))); |
| + int start = title.toString().indexOf(mOrigin); |
| + TextUtils.copySpansFrom(origin, 0, origin.length(), Object.class, title, start); |
| + |
| + message = mContext.getString(R.string.bluetooth_not_found); |
| + SpannableString noneFound = SpanApplier.applySpans( |
| + message, new SpanInfo("<link>", "</link>", |
| + new NoUnderlineClickableSpan(LinkType.RESTART_SEARCH, mContext))); |
| + |
| + String searching = mContext.getString(R.string.bluetooth_searching); |
| + String positiveButton = mContext.getString(R.string.bluetooth_confirm_button); |
| + |
| + SpannableString status = SpanApplier.applySpans( |
| + mContext.getString(R.string.bluetooth_not_seeing_it), |
| + new SpanInfo("<link1>", "</link1>", |
| + new NoUnderlineClickableSpan(LinkType.RESTART_SEARCH, mContext)), |
| + new SpanInfo("<link2>", "</link2>", |
| + new NoUnderlineClickableSpan(LinkType.EXPLAIN_BLUETOOTH, mContext))); |
| + |
| + SpannableString errorMessage = SpanApplier.applySpans( |
| + mContext.getString(R.string.bluetooth_adapter_off), |
| + new SpanInfo("<link>", "</link>", |
| + new NoUnderlineClickableSpan(LinkType.ADAPTER_OFF, mContext))); |
| + SpannableString errorStatus = SpanApplier.applySpans( |
| + mContext.getString(R.string.bluetooth_adapter_off_help), |
| + new SpanInfo("<link>", "</link>", |
| + new NoUnderlineClickableSpan(LinkType.ADAPTER_OFF_HELP, mContext))); |
| + |
| + ItemChooserDialog.ItemChooserLabels labels = |
| + new ItemChooserDialog.ItemChooserLabels(title, searching, noneFound, status, |
| + errorMessage, errorStatus, positiveButton); |
| + mItemChooserDialog = new ItemChooserDialog(mContext, this, labels); |
| + } |
| + |
| + /** |
| + * Dismiss the dialog. |
| + */ |
| + public void dismiss() { |
| + mNativeBluetoothChooserDialogPtr = 0; |
| + mItemChooserDialog.dismiss(); |
| + } |
| + |
| + @Override |
| + public void onItemSelected(String id) { |
| + if (mNativeBluetoothChooserDialogPtr != 0) { |
| + nativeReportDeviceSelected(mNativeBluetoothChooserDialogPtr, id); |
| + } |
| + } |
| + |
| + /** |
| + * A helper class to show a clickable link with underlines turned off. |
| + */ |
| + private class NoUnderlineClickableSpan extends ClickableSpan { |
| + // The type of link this span represents. |
| + private LinkType mLinkType; |
| + |
| + // TODO(finnur): Remove this variable when toasts have been eliminated. |
| + private Context mContext; |
| + |
| + NoUnderlineClickableSpan(LinkType linkType, Context context) { |
| + mLinkType = linkType; |
| + mContext = context; |
| + } |
| + |
| + @Override |
| + public void onClick(View view) { |
| + switch (mLinkType) { |
| + case EXPLAIN_BLUETOOTH: { |
| + // TODO(finnur): Implement. |
| + Toast toast = Toast.makeText( |
| + mContext, "Show help center article", Toast.LENGTH_SHORT); |
| + toast.show(); |
| + break; |
| + } |
| + case EXPLAIN_PARING: { |
| + // TODO(finnur): Implement. |
| + Toast toast = Toast.makeText(mContext, |
| + "Show what it means to be paired with something", Toast.LENGTH_SHORT); |
| + toast.show(); |
| + break; |
| + } |
| + case ADAPTER_OFF: { |
| + Intent intent = new Intent(); |
| + intent.setAction(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS); |
| + mContext.startActivity(intent); |
| + break; |
| + } |
| + case ADAPTER_OFF_HELP: { |
| + // TODO(finnur): Implement. |
| + Toast toast = Toast.makeText(mContext, "Haaaalp!", Toast.LENGTH_SHORT); |
| + toast.show(); |
| + break; |
| + } |
| + case RESTART_SEARCH: { |
| + mItemChooserDialog.clear(); |
| + if (mNativeBluetoothChooserDialogPtr != 0) { |
| + nativeReportRestartSearch(mNativeBluetoothChooserDialogPtr); |
| + } |
| + break; |
| + } |
| + default: |
| + assert false; |
| + } |
| + |
| + // Get rid of the highlight background on selection. |
| + view.invalidate(); |
| + } |
| + |
| + @Override |
| + public void updateDrawState(TextPaint textPaint) { |
| + super.updateDrawState(textPaint); |
| + textPaint.bgColor = Color.TRANSPARENT; |
| + textPaint.setUnderlineText(false); |
| + } |
| + } |
| + |
| + @CalledByNative |
| + private static BluetoothChooserDialog create( |
| + WindowAndroid windowAndroid, String origin, int securityLevel, |
| + long nativeBluetoothChooserDialogPtr) { |
| + Activity activity = windowAndroid.getActivity().get(); |
| + BluetoothChooserDialog dialog = new BluetoothChooserDialog( |
| + activity, origin, securityLevel, nativeBluetoothChooserDialogPtr); |
| + dialog.show(); |
| + return dialog; |
| + } |
| + |
| + @CalledByNative |
| + private void addDevice(String deviceId, String deviceName) { |
| + List<ItemChooserDialog.ItemChooserRow> devices = |
| + new ArrayList<ItemChooserDialog.ItemChooserRow>(); |
| + devices.add(new ItemChooserDialog.ItemChooserRow(deviceId, deviceName)); |
| + mItemChooserDialog.showList(devices); |
| + } |
| + |
| + @CalledByNative |
| + private void closeDialog() { |
| + mItemChooserDialog.dismiss(); |
|
Jeffrey Yasskin
2015/08/31 17:03:53
Dumb question: why doesn't this call this.dismiss(
Finnur
2015/09/01 11:53:50
Not a dumb question at all. Fixed.
|
| + } |
| + |
| + @CalledByNative |
| + private void removeDevice(String deviceId) { |
| + mItemChooserDialog.remove(deviceId); |
| + } |
| + |
| + @CalledByNative |
| + private void notifyAdapterTurnedOff() { |
| + mItemChooserDialog.setErrorState(); |
| + } |
| + |
| + private native void nativeReportDeviceSelected( |
| + long nativeBluetoothChooserAndroid, String deviceId); |
| + private native void nativeReportRestartSearch(long nativeBluetoothChooserAndroid); |
| +} |