Merge "Update audio sharing dialog text." into main
This commit is contained in:
@@ -45,8 +45,8 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/qrcode_view"
|
android:id="@+id/qrcode_view"
|
||||||
android:layout_width="@dimen/qrcode_size"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="@dimen/qrcode_size"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/qr_code_content_description"
|
android:contentDescription="@string/qr_code_content_description"
|
||||||
android:focusable="true" />
|
android:focusable="true" />
|
||||||
|
|
||||||
|
@@ -38,11 +38,11 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/qrcode_view"
|
android:id="@+id/qrcode_view"
|
||||||
android:layout_width="@dimen/qrcode_size"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="@dimen/qrcode_size"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/qr_code_content_description"
|
android:contentDescription="@string/qr_code_content_description"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:paddingTop="70dp"/>
|
android:layout_marginTop="70dp"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/password"
|
android:id="@+id/password"
|
||||||
|
@@ -47,6 +47,15 @@
|
|||||||
android:paddingBottom="24dp"
|
android:paddingBottom="24dp"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/description_text_2"
|
||||||
|
style="@style/DeviceAudioSharingText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:paddingBottom="24dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/device_btn_list"
|
android:id="@+id/device_btn_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@@ -529,6 +529,7 @@
|
|||||||
<dimen name="contrast_button_horizontal_spacing">16dp</dimen>
|
<dimen name="contrast_button_horizontal_spacing">16dp</dimen>
|
||||||
|
|
||||||
<dimen name="audio_streams_qrcode_size">264dp</dimen>
|
<dimen name="audio_streams_qrcode_size">264dp</dimen>
|
||||||
|
<dimen name="audio_streams_qrcode_margin">1.8dp</dimen>
|
||||||
<dimen name="audio_streams_qrcode_preview_size">300dp</dimen>
|
<dimen name="audio_streams_qrcode_preview_size">300dp</dimen>
|
||||||
<dimen name="audio_streams_qrcode_preview_radius">30dp</dimen>
|
<dimen name="audio_streams_qrcode_preview_radius">30dp</dimen>
|
||||||
<dimen name="audio_streams_qrcode_scanner_fragment_padding">16dp</dimen>
|
<dimen name="audio_streams_qrcode_scanner_fragment_padding">16dp</dimen>
|
||||||
|
@@ -13929,6 +13929,10 @@
|
|||||||
<string name="audio_sharing_close_button_label">Close</string>
|
<string name="audio_sharing_close_button_label">Close</string>
|
||||||
<!-- Content for audio sharing share dialog with no device, ask users to connect device [CHAR LIMIT=none]-->
|
<!-- Content for audio sharing share dialog with no device, ask users to connect device [CHAR LIMIT=none]-->
|
||||||
<string name="audio_sharing_dialog_connect_device_content">Connect another pair of compatible headphones, or share your stream\'s name and password with the other person</string>
|
<string name="audio_sharing_dialog_connect_device_content">Connect another pair of compatible headphones, or share your stream\'s name and password with the other person</string>
|
||||||
|
<!-- Content for audio sharing share dialog with no device, ask users to scan qr code [CHAR LIMIT=none]-->
|
||||||
|
<string name="audio_sharing_dialog_qr_code_content">Let others scan this code and listen to your audio\n\nStream name: <xliff:g example="Pixel 8" id="stream_name">%1$s</xliff:g>\nPassword: <xliff:g example="123456" id="password">%2$s</xliff:g></string>
|
||||||
|
<!-- Content for audio sharing share dialog with no device, ask users to pair new device [CHAR LIMIT=none]-->
|
||||||
|
<string name="audio_sharing_dialog_pair_new_device_content">or pair another set of compatible headphones</string>
|
||||||
<!-- Content for audio sharing share dialog with no device, ask users to pair device [CHAR LIMIT=none]-->
|
<!-- Content for audio sharing share dialog with no device, ask users to pair device [CHAR LIMIT=none]-->
|
||||||
<string name="audio_sharing_dialog_pair_device_content">Pair another set of compatible headphones, or share your audio stream QR code with the other person</string>
|
<string name="audio_sharing_dialog_pair_device_content">Pair another set of compatible headphones, or share your audio stream QR code with the other person</string>
|
||||||
<!-- Text for sharing audio sharing state [CHAR LIMIT=none]-->
|
<!-- Text for sharing audio sharing state [CHAR LIMIT=none]-->
|
||||||
|
@@ -18,7 +18,7 @@ package com.android.settings.connecteddevice.audiosharing;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@@ -162,13 +162,13 @@ public class AudioSharingDialogFactory {
|
|||||||
/**
|
/**
|
||||||
* Sets the custom image of the dialog custom body.
|
* Sets the custom image of the dialog custom body.
|
||||||
*
|
*
|
||||||
* @param bitmap The bitmap to be used for the image.
|
* @param drawable The drawable to be used for the image.
|
||||||
* @return This builder.
|
* @return This builder.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public AudioSharingDialogFactory.DialogBuilder setCustomImage(Bitmap bitmap) {
|
public AudioSharingDialogFactory.DialogBuilder setCustomImage(Drawable drawable) {
|
||||||
ImageView image = mCustomBody.findViewById(R.id.description_image);
|
ImageView image = mCustomBody.findViewById(R.id.description_image);
|
||||||
image.setImageBitmap(bitmap);
|
image.setImageDrawable(drawable);
|
||||||
image.setVisibility(View.VISIBLE);
|
image.setVisibility(View.VISIBLE);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -202,6 +202,21 @@ public class AudioSharingDialogFactory {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the custom message below image.
|
||||||
|
*
|
||||||
|
* @param messageRes Resource ID of the string to be used for the message body.
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public AudioSharingDialogFactory.DialogBuilder setCustomMessage2(
|
||||||
|
@StringRes int messageRes) {
|
||||||
|
TextView subTitle = mCustomBody.findViewById(R.id.description_text_2);
|
||||||
|
subTitle.setText(messageRes);
|
||||||
|
subTitle.setVisibility(View.VISIBLE);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the custom device actions of the dialog custom body.
|
* Sets the custom device actions of the dialog custom body.
|
||||||
*
|
*
|
||||||
|
@@ -17,13 +17,13 @@
|
|||||||
package com.android.settings.connecteddevice.audiosharing;
|
package com.android.settings.connecteddevice.audiosharing;
|
||||||
|
|
||||||
import static com.android.settings.connecteddevice.audiosharing.AudioSharingDashboardFragment.SHARE_THEN_PAIR_REQUEST_CODE;
|
import static com.android.settings.connecteddevice.audiosharing.AudioSharingDashboardFragment.SHARE_THEN_PAIR_REQUEST_CODE;
|
||||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsQrCodeFragment.getQrCodeBitmap;
|
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsQrCodeFragment.getQrCodeDrawable;
|
||||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_PAIR_AND_JOIN_SHARING;
|
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_PAIR_AND_JOIN_SHARING;
|
||||||
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
@@ -45,6 +45,7 @@ import com.android.settingslib.bluetooth.BluetoothUtils;
|
|||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
|
public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
|
||||||
@@ -159,7 +160,6 @@ public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
|
|||||||
}
|
}
|
||||||
if (deviceItems.isEmpty()) {
|
if (deviceItems.isEmpty()) {
|
||||||
builder.setTitle(R.string.audio_sharing_share_dialog_title)
|
builder.setTitle(R.string.audio_sharing_share_dialog_title)
|
||||||
.setCustomMessage(R.string.audio_sharing_dialog_connect_device_content)
|
|
||||||
.setCustomPositiveButton(
|
.setCustomPositiveButton(
|
||||||
R.string.audio_sharing_pair_button_label,
|
R.string.audio_sharing_pair_button_label,
|
||||||
v -> {
|
v -> {
|
||||||
@@ -183,14 +183,23 @@ public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
|
|||||||
});
|
});
|
||||||
BluetoothLeBroadcastMetadata metadata = arguments.getParcelable(
|
BluetoothLeBroadcastMetadata metadata = arguments.getParcelable(
|
||||||
BUNDLE_KEY_BROADCAST_METADATA, BluetoothLeBroadcastMetadata.class);
|
BUNDLE_KEY_BROADCAST_METADATA, BluetoothLeBroadcastMetadata.class);
|
||||||
Bitmap qrCodeBitmap = metadata == null ? null : getQrCodeBitmap(metadata,
|
Drawable qrCodeDrawable = metadata == null ? null : getQrCodeDrawable(metadata,
|
||||||
getContext()).orElse(null);
|
getContext()).orElse(null);
|
||||||
if (qrCodeBitmap != null) {
|
if (qrCodeDrawable != null) {
|
||||||
builder.setCustomImage(qrCodeBitmap)
|
builder.setCustomImage(qrCodeDrawable)
|
||||||
.setCustomNegativeButton(com.android.settings.R.string.cancel,
|
.setCustomMessage(
|
||||||
|
getString(
|
||||||
|
R.string.audio_sharing_dialog_qr_code_content,
|
||||||
|
metadata.getBroadcastName(),
|
||||||
|
new String(
|
||||||
|
metadata.getBroadcastCode(),
|
||||||
|
StandardCharsets.UTF_8)))
|
||||||
|
.setCustomMessage2(R.string.audio_sharing_dialog_pair_new_device_content)
|
||||||
|
.setCustomNegativeButton(R.string.audio_streams_dialog_close,
|
||||||
v -> onCancelClick());
|
v -> onCancelClick());
|
||||||
} else {
|
} else {
|
||||||
builder.setCustomImage(R.drawable.audio_sharing_guidance)
|
builder.setCustomImage(R.drawable.audio_sharing_guidance)
|
||||||
|
.setCustomMessage(R.string.audio_sharing_dialog_connect_device_content)
|
||||||
.setCustomNegativeButton(
|
.setCustomNegativeButton(
|
||||||
R.string.audio_sharing_qrcode_button_label,
|
R.string.audio_sharing_qrcode_button_label,
|
||||||
v -> {
|
v -> {
|
||||||
|
@@ -19,7 +19,9 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
|||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -30,6 +32,8 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
|
||||||
|
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.bluetooth.Utils;
|
import com.android.settings.bluetooth.Utils;
|
||||||
@@ -70,15 +74,16 @@ public class AudioStreamsQrCodeFragment extends InstrumentedFragment {
|
|||||||
if (broadcastMetadata == null) {
|
if (broadcastMetadata == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bitmap bm = getQrCodeBitmap(broadcastMetadata, getActivity()).orElse(null);
|
Drawable drawable = getQrCodeDrawable(broadcastMetadata, getActivity()).orElse(
|
||||||
if (bm == null) {
|
null);
|
||||||
|
if (drawable == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadUtils.postOnMainThread(
|
ThreadUtils.postOnMainThread(
|
||||||
() -> {
|
() -> {
|
||||||
((ImageView) view.requireViewById(R.id.qrcode_view))
|
((ImageView) view.requireViewById(R.id.qrcode_view))
|
||||||
.setImageBitmap(bm);
|
.setImageDrawable(drawable);
|
||||||
if (broadcastMetadata.getBroadcastCode() != null) {
|
if (broadcastMetadata.getBroadcastCode() != null) {
|
||||||
String password =
|
String password =
|
||||||
new String(
|
new String(
|
||||||
@@ -101,28 +106,33 @@ public class AudioStreamsQrCodeFragment extends InstrumentedFragment {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets an optional bitmap from metadata. */
|
/** Gets an optional drawable from metadata. */
|
||||||
public static Optional<Bitmap> getQrCodeBitmap(@Nullable BluetoothLeBroadcastMetadata metadata,
|
public static Optional<Drawable> getQrCodeDrawable(
|
||||||
|
@Nullable BluetoothLeBroadcastMetadata metadata,
|
||||||
Context context) {
|
Context context) {
|
||||||
if (metadata == null) {
|
if (metadata == null) {
|
||||||
Log.d(TAG, "getQrCodeBitmap: broadcastMetadata is empty!");
|
Log.d(TAG, "getQrCodeDrawable: broadcastMetadata is empty!");
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
String metadataStr = BluetoothLeBroadcastMetadataExt.INSTANCE.toQrCodeString(metadata);
|
String metadataStr = BluetoothLeBroadcastMetadataExt.INSTANCE.toQrCodeString(metadata);
|
||||||
if (metadataStr.isEmpty()) {
|
if (metadataStr.isEmpty()) {
|
||||||
Log.d(TAG, "getQrCodeBitmap: metadataStr is empty!");
|
Log.d(TAG, "getQrCodeDrawable: metadataStr is empty!");
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
Log.d(TAG, "getQrCodeBitmap: metadata : " + metadata);
|
Log.d(TAG, "getQrCodeDrawable: metadata : " + metadata);
|
||||||
try {
|
try {
|
||||||
int qrcodeSize =
|
Resources resources = context.getResources();
|
||||||
context.getResources().getDimensionPixelSize(R.dimen.audio_streams_qrcode_size);
|
int qrcodeSize = resources.getDimensionPixelSize(R.dimen.audio_streams_qrcode_size);
|
||||||
Bitmap bitmap = QrCodeGenerator.encodeQrCode(metadataStr, qrcodeSize);
|
int margin = resources.getDimensionPixelSize(R.dimen.audio_streams_qrcode_margin);
|
||||||
return Optional.of(bitmap);
|
Bitmap bitmap = QrCodeGenerator.encodeQrCode(metadataStr, qrcodeSize, margin);
|
||||||
|
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(resources, bitmap);
|
||||||
|
drawable.setCornerRadius(resources.getDimensionPixelSize(
|
||||||
|
R.dimen.audio_streams_qrcode_preview_radius));
|
||||||
|
return Optional.of(drawable);
|
||||||
} catch (WriterException e) {
|
} catch (WriterException e) {
|
||||||
Log.d(
|
Log.d(
|
||||||
TAG,
|
TAG,
|
||||||
"getQrCodeBitmap: broadcastMetadata "
|
"getQrCodeDrawable: broadcastMetadata "
|
||||||
+ metadata
|
+ metadata
|
||||||
+ " qrCode generation exception "
|
+ " qrCode generation exception "
|
||||||
+ e);
|
+ e);
|
||||||
|
@@ -60,6 +60,7 @@ import org.robolectric.annotation.Config;
|
|||||||
import org.robolectric.shadow.api.Shadow;
|
import org.robolectric.shadow.api.Shadow;
|
||||||
import org.robolectric.shadows.androidx.fragment.FragmentController;
|
import org.robolectric.shadows.androidx.fragment.FragmentController;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
@@ -263,6 +264,18 @@ public class AudioSharingDialogFragmentTest {
|
|||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
ImageView image = dialog.findViewById(R.id.description_image);
|
ImageView image = dialog.findViewById(R.id.description_image);
|
||||||
assertThat(image).isNotNull();
|
assertThat(image).isNotNull();
|
||||||
|
TextView text = dialog.findViewById(R.id.description_text);
|
||||||
|
assertThat(text).isNotNull();
|
||||||
|
assertThat(METADATA).isNotNull();
|
||||||
|
assertThat(text.getText().toString()).isEqualTo(
|
||||||
|
mParent.getString(R.string.audio_sharing_dialog_qr_code_content,
|
||||||
|
METADATA.getBroadcastName(), new String(
|
||||||
|
METADATA.getBroadcastCode(),
|
||||||
|
StandardCharsets.UTF_8)));
|
||||||
|
TextView textBottom = dialog.findViewById(R.id.description_text_2);
|
||||||
|
assertThat(textBottom).isNotNull();
|
||||||
|
assertThat(textBottom.getText().toString()).isEqualTo(
|
||||||
|
mParent.getString(R.string.audio_sharing_dialog_pair_new_device_content));
|
||||||
Button cancelBtn = dialog.findViewById(R.id.negative_btn);
|
Button cancelBtn = dialog.findViewById(R.id.negative_btn);
|
||||||
assertThat(cancelBtn).isNotNull();
|
assertThat(cancelBtn).isNotNull();
|
||||||
cancelBtn.performClick();
|
cancelBtn.performClick();
|
||||||
|
Reference in New Issue
Block a user