[Le Audio] Move BT QR code scanner from Settingslibs to Settings

Systemui memory regression, so we have to move the qr code activity back to Settings

Bug: 228031398
Test: manual
Change-Id: Ic30291e6d752c6c770c40e1329d9f95ceec8cca6
This commit is contained in:
Zoey Chen
2022-05-12 11:27:40 +08:00
parent 56c7f91cea
commit 4b345980c3
12 changed files with 647 additions and 1 deletions

View File

@@ -4474,6 +4474,16 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<activity
android:name="com.android.settings.bluetooth.QrCodeScanModeActivity"
android:permission="android.permission.BLUETOOTH_CONNECT"
android:exported="true">
<intent-filter>
<action android:name="android.settings.BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<!-- This is the longest AndroidManifest.xml ever. --> <!-- This is the longest AndroidManifest.xml ever. -->
</application> </application>
</manifest> </manifest>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2022 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp"
android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path android:fillColor="@android:color/white"
android:pathData="M2,7V2H7V4H4V7ZM2,22V17H4V20H7V22ZM17,22V20H20V17H22V22ZM20,7V4H17V2H22V7ZM17.5,17.5H19V19H17.5ZM17.5,14.5H19V16H17.5ZM16,16H17.5V17.5H16ZM14.5,17.5H16V19H14.5ZM13,16H14.5V17.5H13ZM16,13H17.5V14.5H16ZM14.5,14.5H16V16H14.5ZM13,13H14.5V14.5H13ZM19,5V11H13V5ZM11,13V19H5V13ZM11,5V11H5V5ZM9.5,17.5V14.5H6.5V17.5ZM9.5,9.5V6.5H6.5V9.5ZM17.5,9.5V6.5H14.5V9.5Z"/>
</vector>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2022 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2022 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/sud_layout_icon_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_marginBottom="35dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/sud_layout_icon"
android:src="@drawable/ic_qr_code_scanner"
android:tint="?androidprv:attr/colorAccentPrimaryVariant"
android:layout_width="@dimen/qrcode_icon_size"
android:layout_height="@dimen/qrcode_icon_size"
android:contentDescription="@null"/>
<TextView
android:id="@+id/sud_layout_title"
style="@style/QrCodeScanner"
android:textSize="24sp"
android:text="@string/bluetooth_find_broadcast_button_scan"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="19dp"/>
<TextView
android:id="@+id/sud_layout_subtitle"
style="@style/QrCodeScanner"
android:text="@string/bt_le_audio_scan_qr_code_scanner"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="7"
android:orientation="vertical">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:gravity="center"
android:clipChildren="true">
<TextureView
android:id="@+id/preview_view"
android:layout_marginStart="@dimen/qrcode_preview_margin"
android:layout_marginEnd="@dimen/qrcode_preview_margin"
android:layout_width="match_parent"
android:layout_height="@dimen/qrcode_preview_size"/>
</FrameLayout>
<TextView
android:id="@+id/error_message"
style="@style/TextAppearance.ErrorText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="?attr/sudMarginStart"
android:layout_marginEnd="?attr/sudMarginEnd"
android:gravity="center"
android:layout_gravity="center"
android:visibility="invisible"/>
</LinearLayout>
</LinearLayout>

View File

@@ -485,4 +485,9 @@
<!-- Sims/Data mobile/Calls/SMS select dialog--> <!-- Sims/Data mobile/Calls/SMS select dialog-->
<dimen name="sims_select_margin_bottom">24dp</dimen> <dimen name="sims_select_margin_bottom">24dp</dimen>
<dimen name="sims_select_margin_top">8dp</dimen> <dimen name="sims_select_margin_top">8dp</dimen>
<!-- QR code picture size -->
<dimen name="qrcode_preview_margin">40dp</dimen>
<dimen name="qrcode_preview_radius">30dp</dimen>
<dimen name="qrcode_icon_size">27dp</dimen>
</resources> </resources>

View File

@@ -14163,4 +14163,11 @@
<string name="find_broadcast_password_dialog_connection_error">Can\u2019t connect. Try again.</string> <string name="find_broadcast_password_dialog_connection_error">Can\u2019t connect. Try again.</string>
<!-- The error message of enter password dialog in bluetooth find broadcast page [CHAR LIMIT=none] --> <!-- The error message of enter password dialog in bluetooth find broadcast page [CHAR LIMIT=none] -->
<string name="find_broadcast_password_dialog_password_error">Wrong password</string> <string name="find_broadcast_password_dialog_password_error">Wrong password</string>
<!-- [CHAR LIMIT=NONE] Le audio QR code scanner sub-title -->
<string name="bt_le_audio_scan_qr_code_scanner">To start listening, center the QR code below</string>
<!-- [CHAR LIMIT=NONE] Hint for QR code process failure -->
<string name="bt_le_audio_qr_code_is_not_valid_format">QR code isn\u0027t a valid format</string>
</resources> </resources>

View File

@@ -962,4 +962,11 @@
<item name="android:minWidth">0dp</item> <item name="android:minWidth">0dp</item>
<item name="android:textAllCaps">false</item> <item name="android:textAllCaps">false</item>
</style> </style>
<style name="QrCodeScanner">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textSize">16sp</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textDirection">locale</item>
</style>
</resources> </resources>

View File

@@ -33,7 +33,6 @@ import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.qrcode.QrCodeScanModeActivity;
import com.android.settingslib.widget.LayoutPreference; import com.android.settingslib.widget.LayoutPreference;
/** /**

View File

@@ -0,0 +1,111 @@
/**
* Copyright (C) 2022 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 com.android.settings.bluetooth;
import static com.android.settingslib.bluetooth.BluetoothBroadcastUtils.EXTRA_BLUETOOTH_DEVICE_SINK;
import static com.android.settingslib.bluetooth.BluetoothBroadcastUtils.EXTRA_BLUETOOTH_SINK_IS_GROUP;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import androidx.fragment.app.FragmentTransaction;
import com.android.settingslib.R;
import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
import com.android.settingslib.bluetooth.BluetoothUtils;
//TODO (b/232365943): Add test case for tthe QrCode UI.
public class QrCodeScanModeActivity extends QrCodeScanModeBaseActivity {
private static final boolean DEBUG = BluetoothUtils.D;
private static final String TAG = "QrCodeScanModeActivity";
private boolean mIsGroupOp;
private BluetoothDevice mSink;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void handleIntent(Intent intent) {
String action = intent != null ? intent.getAction() : null;
if (DEBUG) {
Log.d(TAG, "handleIntent(), action = " + action);
}
if (action == null) {
finish();
return;
}
switch (action) {
case BluetoothBroadcastUtils.ACTION_BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER:
showQrCodeScannerFragment(intent);
break;
default:
if (DEBUG) {
Log.e(TAG, "Launch with an invalid action");
}
finish();
}
}
protected void showQrCodeScannerFragment(Intent intent) {
if (intent == null) {
if (DEBUG) {
Log.d(TAG, "intent is null, can not get bluetooth information from intent.");
}
return;
}
if (DEBUG) {
Log.d(TAG, "showQrCodeScannerFragment");
}
mSink = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE_SINK);
mIsGroupOp = intent.getBooleanExtra(EXTRA_BLUETOOTH_SINK_IS_GROUP, false);
if (DEBUG) {
Log.d(TAG, "get extra from intent");
}
QrCodeScanModeFragment fragment =
(QrCodeScanModeFragment) mFragmentManager.findFragmentByTag(
BluetoothBroadcastUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
if (fragment == null) {
fragment = new QrCodeScanModeFragment(mIsGroupOp, mSink);
} else {
if (fragment.isVisible()) {
return;
}
// When the fragment in back stack but not on top of the stack, we can simply pop
// stack because current fragment transactions are arranged in an order
mFragmentManager.popBackStackImmediate();
return;
}
final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment,
BluetoothBroadcastUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
fragmentTransaction.commit();
}
}

View File

@@ -0,0 +1,46 @@
/**
* Copyright (C) 2022 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 com.android.settings.bluetooth;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.FragmentManager;
import com.android.settingslib.R;
import com.android.settingslib.core.lifecycle.ObservableActivity;
public abstract class QrCodeScanModeBaseActivity extends ObservableActivity {
protected FragmentManager mFragmentManager;
protected abstract void handleIntent(Intent intent);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.SudThemeGlifV3_DayNight);
setContentView(R.layout.qrcode_scan_mode_activity);
mFragmentManager = getSupportFragmentManager();
if (savedInstanceState == null) {
handleIntent(getIntent());
}
}
}

View File

@@ -0,0 +1,63 @@
/**
* Copyright (C) 2022 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 com.android.settings.bluetooth;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.content.Context;
import android.util.Log;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastMetadata;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
public class QrCodeScanModeController {
private static final boolean DEBUG = BluetoothUtils.D;
private static final String TAG = "QrCodeScanModeController";
private LocalBluetoothLeBroadcastMetadata mLocalBroadcastMetadata;
private LocalBluetoothLeBroadcastAssistant mLocalBroadcastAssistant;
private LocalBluetoothManager mLocalBluetoothManager;
private LocalBluetoothProfileManager mProfileManager;
public QrCodeScanModeController(Context context) {
if (DEBUG) {
Log.d(TAG, "QrCodeScanModeController constructor.");
}
mLocalBluetoothManager = Utils.getLocalBtManager(context);
mProfileManager = mLocalBluetoothManager.getProfileManager();
mLocalBroadcastMetadata = new LocalBluetoothLeBroadcastMetadata();
CachedBluetoothDeviceManager cachedDeviceManager = new CachedBluetoothDeviceManager(context,
mLocalBluetoothManager);
mLocalBroadcastAssistant = new LocalBluetoothLeBroadcastAssistant(context,
cachedDeviceManager, mProfileManager);
}
private BluetoothLeBroadcastMetadata convertToBroadcastMetadata(String qrCodeString) {
return mLocalBroadcastMetadata.convertToBroadcastMetadata(qrCodeString);
}
public void addSource(BluetoothDevice sink, String sourceMetadata,
boolean isGroupOp) {
mLocalBroadcastAssistant.addSource(sink,
convertToBroadcastMetadata(sourceMetadata), isGroupOp);
}
}

View File

@@ -0,0 +1,243 @@
/**
* Copyright (C) 2022 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 com.android.settings.bluetooth;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.Size;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.accessibility.AccessibilityEvent;
import android.widget.TextView;
import com.android.settings.core.InstrumentedFragment;
import com.android.settingslib.R;
import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.core.lifecycle.ObservableFragment;
import com.android.settingslib.qrcode.QrCamera;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
public class QrCodeScanModeFragment extends InstrumentedFragment implements
TextureView.SurfaceTextureListener,
QrCamera.ScannerCallback {
private static final boolean DEBUG = BluetoothUtils.D;
private static final String TAG = "QrCodeScanModeFragment";
/** Message sent to hide error message */
private static final int MESSAGE_HIDE_ERROR_MESSAGE = 1;
/** Message sent to show error message */
private static final int MESSAGE_SHOW_ERROR_MESSAGE = 2;
/** Message sent to broadcast QR code */
private static final int MESSAGE_SCAN_BROADCAST_SUCCESS = 3;
private static final long SHOW_ERROR_MESSAGE_INTERVAL = 10000;
private static final long SHOW_SUCCESS_SQUARE_INTERVAL = 1000;
private boolean mIsGroupOp;
private int mCornerRadius;
private BluetoothDevice mSink;
private String mBroadcastMetadata;
private Context mContext;
private QrCamera mCamera;
private QrCodeScanModeController mController;
private TextureView mTextureView;
private TextView mSummary;
private TextView mErrorMessage;
public QrCodeScanModeFragment(boolean isGroupOp, BluetoothDevice sink) {
mIsGroupOp = isGroupOp;
mSink = sink;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getContext();
mController = new QrCodeScanModeController(mContext);
}
@Override
public final View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.qrcode_scanner_fragment, container,
/* attachToRoot */ false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mTextureView = view.findViewById(R.id.preview_view);
mCornerRadius = mContext.getResources().getDimensionPixelSize(
R.dimen.qrcode_preview_radius);
mTextureView.setSurfaceTextureListener(this);
mTextureView.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(0,0, view.getWidth(), view.getHeight(), mCornerRadius);
}
});
mTextureView.setClipToOutline(true);
mErrorMessage = view.findViewById(R.id.error_message);
}
private void initCamera(SurfaceTexture surface) {
// Check if the camera has already created.
if (mCamera == null) {
mCamera = new QrCamera(mContext, this);
mCamera.start(surface);
}
}
private void destroyCamera() {
if (mCamera != null) {
mCamera.stop();
mCamera = null;
}
}
@Override
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
initCamera(surface);
}
@Override
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width,
int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
destroyCamera();
return true;
}
@Override
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
}
@Override
public void handleSuccessfulResult(String qrCode) {
if (DEBUG) {
Log.d(TAG, "handleSuccessfulResult(), get the qr code string.");
}
mBroadcastMetadata = qrCode;
handleBtLeAudioScanner();
}
@Override
public void handleCameraFailure() {
destroyCamera();
}
@Override
public Size getViewSize() {
return new Size(mTextureView.getWidth(), mTextureView.getHeight());
}
@Override
public Rect getFramePosition(Size previewSize, int cameraOrientation) {
return new Rect(0, 0, previewSize.getHeight(), previewSize.getHeight());
}
@Override
public void setTransform(Matrix transform) {
mTextureView.setTransform(transform);
}
@Override
public boolean isValid(String qrCode) {
if (qrCode.startsWith(BluetoothBroadcastUtils.SCHEME_BT_BROADCAST_METADATA)) {
return true;
} else {
showErrorMessage(R.string.bt_le_audio_qr_code_is_not_valid_format);
return false;
}
}
protected boolean isDecodeTaskAlive() {
return mCamera != null && mCamera.isDecodeTaskAlive();
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_HIDE_ERROR_MESSAGE:
mErrorMessage.setVisibility(View.INVISIBLE);
break;
case MESSAGE_SHOW_ERROR_MESSAGE:
final String errorMessage = (String) msg.obj;
mErrorMessage.setVisibility(View.VISIBLE);
mErrorMessage.setText(errorMessage);
mErrorMessage.sendAccessibilityEvent(
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
// Cancel any pending messages to hide error view and requeue the message so
// user has time to see error
removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
SHOW_ERROR_MESSAGE_INTERVAL);
break;
case MESSAGE_SCAN_BROADCAST_SUCCESS:
mController.addSource(mSink, mBroadcastMetadata, mIsGroupOp);
updateSummary();
mSummary.sendAccessibilityEvent(
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
break;
default:
}
}
};
private void showErrorMessage(@StringRes int messageResId) {
final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
getString(messageResId));
message.sendToTarget();
}
private void handleBtLeAudioScanner() {
Message message = mHandler.obtainMessage(MESSAGE_SCAN_BROADCAST_SUCCESS);
mHandler.sendMessageDelayed(message, SHOW_SUCCESS_SQUARE_INTERVAL);
}
private void updateSummary() {
mSummary.setText(getString(R.string.bt_le_audio_scan_qr_code_scanner,
null /* broadcast_name*/));;
}
@Override
public int getMetricsCategory() {
return SettingsEnums.LE_AUDIO_BROADCAST_SCAN_QR_CODE;
}
}