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 android.bluetooth.BluetoothProfile;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.view.View;
23 import android.widget.Button;
24 import android.widget.LinearLayout;
25 import android.widget.TextView;
26 
27 import androidx.preference.PreferenceCategory;
28 import androidx.preference.PreferenceScreen;
29 
30 import com.android.settings.R;
31 import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
32 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
33 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
34 import com.android.settingslib.bluetooth.LocalBluetoothManager;
35 import com.android.settingslib.core.lifecycle.Lifecycle;
36 import com.android.settingslib.widget.LayoutPreference;
37 
38 /**
39  * This class adds a header to display the action button for joining the broadcast session
40  * by scanning QR code and leaving the broadcast session
41  */
42 public class BluetoothFindBroadcastsHeaderController extends BluetoothDetailsController {
43     private static final String TAG = "BtFindBroadcastCtrl";
44 
45     private static final String KEY_BROADCAST_HEADER = "bluetooth_find_broadcast_header";
46     private static final String KEY_BROADCAST_SOURCE_LIST = "broadcast_source_list";
47 
48     LayoutPreference mLayoutPreference;
49     PreferenceCategory mBroadcastSourceList;
50     TextView mTitle;
51     TextView mSummary;
52     Button mBtnFindBroadcast;
53     LinearLayout mBtnBroadcastLayout;
54     Button mBtnLeaveBroadcast;
55     Button mBtnScanQrCode;
56     BluetoothFindBroadcastsFragment mBluetoothFindBroadcastsFragment;
BluetoothFindBroadcastsHeaderController(Context context, BluetoothFindBroadcastsFragment fragment, CachedBluetoothDevice device, Lifecycle lifecycle, LocalBluetoothManager bluetoothManager)57     public BluetoothFindBroadcastsHeaderController(Context context,
58             BluetoothFindBroadcastsFragment fragment, CachedBluetoothDevice device,
59             Lifecycle lifecycle, LocalBluetoothManager bluetoothManager) {
60         super(context, fragment, device, lifecycle);
61         mBluetoothFindBroadcastsFragment = fragment;
62     }
63 
64     @Override
init(PreferenceScreen screen)65     protected void init(PreferenceScreen screen) {
66         mLayoutPreference = screen.findPreference(KEY_BROADCAST_HEADER);
67         mBroadcastSourceList = screen.findPreference(KEY_BROADCAST_SOURCE_LIST);
68 
69         refresh();
70     }
71 
72     @Override
refresh()73     protected void refresh() {
74         if (mLayoutPreference == null || mCachedDevice == null) {
75             return;
76         }
77 
78         mTitle = mLayoutPreference.findViewById(R.id.entity_header_title);
79         mTitle.setText(mCachedDevice.getName());
80         mSummary = mLayoutPreference.findViewById(R.id.entity_header_summary);
81         mSummary.setText("");
82 
83         mBtnFindBroadcast = mLayoutPreference.findViewById(R.id.button_find_broadcast);
84         mBtnFindBroadcast.setOnClickListener(v -> scanBroadcastSource());
85         mBtnBroadcastLayout = mLayoutPreference.findViewById(R.id.button_broadcast_layout);
86         mBtnLeaveBroadcast = mLayoutPreference.findViewById(R.id.button_leave_broadcast);
87         mBtnLeaveBroadcast.setOnClickListener(v -> leaveBroadcastSession());
88         mBtnScanQrCode = mLayoutPreference.findViewById(R.id.button_scan_qr_code);
89         mBtnScanQrCode.setOnClickListener(v -> launchQrCodeScanner());
90 
91         updateHeaderLayout();
92     }
93 
isBroadcastSourceExist()94     private boolean isBroadcastSourceExist() {
95         return mBroadcastSourceList.getPreferenceCount() > 0;
96     }
97 
updateHeaderLayout()98     private void updateHeaderLayout() {
99         if (isBroadcastSourceExist()) {
100             mBtnFindBroadcast.setVisibility(View.GONE);
101             mBtnBroadcastLayout.setVisibility(View.VISIBLE);
102         } else {
103             mBtnFindBroadcast.setVisibility(View.VISIBLE);
104             mBtnBroadcastLayout.setVisibility(View.GONE);
105         }
106 
107         mBtnLeaveBroadcast.setEnabled(false);
108         if (mBluetoothFindBroadcastsFragment != null && mCachedDevice != null) {
109             LocalBluetoothLeBroadcastAssistant broadcastAssistant =
110                     mBluetoothFindBroadcastsFragment.getLeBroadcastAssistant();
111             if (broadcastAssistant != null
112                     && broadcastAssistant.getConnectionStatus(mCachedDevice.getDevice())
113                     == BluetoothProfile.STATE_CONNECTED) {
114                 mBtnLeaveBroadcast.setEnabled(true);
115             }
116         }
117     }
118 
scanBroadcastSource()119     private void scanBroadcastSource() {
120         // TODO(b/231543455) : Using the BluetoothDeviceUpdater to refactor it.
121         if (mBluetoothFindBroadcastsFragment == null) {
122             return;
123         }
124         mBluetoothFindBroadcastsFragment.scanBroadcastSource();
125     }
126 
leaveBroadcastSession()127     private void leaveBroadcastSession() {
128         if (mBluetoothFindBroadcastsFragment == null) {
129             return;
130         }
131         mBluetoothFindBroadcastsFragment.leaveBroadcastSession();
132     }
133 
launchQrCodeScanner()134     private void launchQrCodeScanner() {
135         final Intent intent = new Intent(mContext, QrCodeScanModeActivity.class);
136         intent.setAction(BluetoothBroadcastUtils.ACTION_BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER)
137                 .putExtra(BluetoothBroadcastUtils.EXTRA_BLUETOOTH_SINK_IS_GROUP, true)
138                 .putExtra(BluetoothBroadcastUtils.EXTRA_BLUETOOTH_DEVICE_SINK,
139                         mCachedDevice.getDevice());
140         mBluetoothFindBroadcastsFragment.startActivityForResult(intent,
141                 BluetoothFindBroadcastsFragment.REQUEST_SCAN_BT_BROADCAST_QR_CODE);
142     }
143 
144     @Override
onDeviceAttributesChanged()145     public void onDeviceAttributesChanged() {
146         if (mCachedDevice != null) {
147             refresh();
148         }
149     }
150 
151     @Override
getPreferenceKey()152     public String getPreferenceKey() {
153         return KEY_BROADCAST_HEADER;
154     }
155 
156     /**
157      * Updates the UI
158      */
refreshUi()159     public void refreshUi() {
160         updateHeaderLayout();
161     }
162 }
163