1 /**
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.bluetooth;
18 
19 import static com.android.settingslib.bluetooth.BluetoothBroadcastUtils.EXTRA_BLUETOOTH_DEVICE_SINK;
20 import static com.android.settingslib.bluetooth.BluetoothBroadcastUtils.EXTRA_BLUETOOTH_SINK_IS_GROUP;
21 import static com.android.settingslib.flags.Flags.legacyLeAudioSharing;
22 
23 import android.bluetooth.BluetoothDevice;
24 import android.content.Intent;
25 import android.os.Bundle;
26 import android.util.Log;
27 
28 import androidx.fragment.app.FragmentTransaction;
29 
30 import com.android.settings.R;
31 import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
32 import com.android.settingslib.bluetooth.BluetoothUtils;
33 
34 /**
35  * Finding a broadcast through QR code.
36  *
37  * To use intent action {@link BluetoothBroadcastUtils#ACTION_BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER},
38  * specify the bluetooth device sink of the broadcast to be provisioned in
39  * {@link BluetoothBroadcastUtils#EXTRA_BLUETOOTH_DEVICE_SINK} and check the operation for all
40  * coordinated set members throughout one session or not by
41  * {@link BluetoothBroadcastUtils#EXTRA_BLUETOOTH_SINK_IS_GROUP}.
42  */
43 public class QrCodeScanModeActivity extends QrCodeScanModeBaseActivity {
44     private static final boolean DEBUG = BluetoothUtils.D;
45     private static final String TAG = "QrCodeScanModeActivity";
46 
47     private boolean mIsGroupOp;
48     private BluetoothDevice mSink;
49 
50     @Override
onCreate(Bundle savedInstanceState)51     protected void onCreate(Bundle savedInstanceState) {
52         super.onCreate(savedInstanceState);
53     }
54 
55     @Override
handleIntent(Intent intent)56     protected void handleIntent(Intent intent) {
57         if (!legacyLeAudioSharing()) {
58             finish();
59         }
60 
61         String action = intent != null ? intent.getAction() : null;
62         if (DEBUG) {
63             Log.d(TAG, "handleIntent(), action = " + action);
64         }
65 
66         if (action == null) {
67             finish();
68             return;
69         }
70 
71         switch (action) {
72             case BluetoothBroadcastUtils.ACTION_BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER:
73                 showQrCodeScannerFragment(intent);
74                 break;
75             default:
76                 if (DEBUG) {
77                     Log.e(TAG, "Launch with an invalid action");
78                 }
79                 finish();
80         }
81     }
82 
showQrCodeScannerFragment(Intent intent)83     protected void showQrCodeScannerFragment(Intent intent) {
84         if (intent == null) {
85             if (DEBUG) {
86                 Log.d(TAG, "intent is null, can not get bluetooth information from intent.");
87             }
88             return;
89         }
90 
91         if (DEBUG) {
92             Log.d(TAG, "showQrCodeScannerFragment");
93         }
94 
95         mSink = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE_SINK);
96         mIsGroupOp = intent.getBooleanExtra(EXTRA_BLUETOOTH_SINK_IS_GROUP, false);
97         if (DEBUG) {
98             Log.d(TAG, "get extra from intent");
99         }
100 
101         QrCodeScanModeFragment fragment =
102                 (QrCodeScanModeFragment) mFragmentManager.findFragmentByTag(
103                         BluetoothBroadcastUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
104 
105         if (fragment == null) {
106             fragment = new QrCodeScanModeFragment();
107         } else {
108             if (fragment.isVisible()) {
109                 return;
110             }
111 
112             // When the fragment in back stack but not on top of the stack, we can simply pop
113             // stack because current fragment transactions are arranged in an order
114             mFragmentManager.popBackStackImmediate();
115             return;
116         }
117         final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
118 
119         fragmentTransaction.replace(R.id.fragment_container, fragment,
120                 BluetoothBroadcastUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
121         fragmentTransaction.commit();
122     }
123 }
124 
125