1 /*
2  * Copyright (C) 2018 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.connecteddevice;
18 
19 import android.bluetooth.BluetoothAdapter;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.pm.PackageManager;
25 import android.text.BidiFormatter;
26 import android.text.TextUtils;
27 
28 import androidx.annotation.VisibleForTesting;
29 import androidx.preference.PreferenceScreen;
30 
31 import com.android.settings.R;
32 import com.android.settings.bluetooth.AlwaysDiscoverable;
33 import com.android.settings.bluetooth.Utils;
34 import com.android.settings.core.BasePreferenceController;
35 import com.android.settingslib.bluetooth.LocalBluetoothManager;
36 import com.android.settingslib.core.lifecycle.LifecycleObserver;
37 import com.android.settingslib.core.lifecycle.events.OnStart;
38 import com.android.settingslib.core.lifecycle.events.OnStop;
39 import com.android.settingslib.widget.FooterPreference;
40 
41 /**
42  * Controller that shows and updates the bluetooth device name
43  */
44 public class DiscoverableFooterPreferenceController extends BasePreferenceController
45         implements LifecycleObserver, OnStart, OnStop {
46     private static final String KEY = "discoverable_footer_preference";
47 
48     @VisibleForTesting
49     BroadcastReceiver mBluetoothChangedReceiver;
50     @VisibleForTesting
51     LocalBluetoothManager mLocalManager;
52     private BluetoothAdapter mBluetoothAdapter;
53     private AlwaysDiscoverable mAlwaysDiscoverable;
54     private FooterPreference mPreference;
55 
DiscoverableFooterPreferenceController(Context context, String key)56     public DiscoverableFooterPreferenceController(Context context, String key) {
57         super(context, key);
58         mLocalManager = Utils.getLocalBtManager(context);
59         if (mLocalManager == null) {
60             return;
61         }
62         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
63         mAlwaysDiscoverable = new AlwaysDiscoverable(context);
64         initReceiver();
65     }
66 
67     @Override
displayPreference(PreferenceScreen screen)68     public void displayPreference(PreferenceScreen screen) {
69         super.displayPreference(screen);
70         mPreference = screen.findPreference(getPreferenceKey());
71     }
72 
73     @Override
getAvailabilityStatus()74     public int getAvailabilityStatus() {
75         return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
76                 ? AVAILABLE_UNSEARCHABLE
77                 : UNSUPPORTED_ON_DEVICE;
78     }
79 
80     @Override
onStart()81     public void onStart() {
82         if (mLocalManager == null) {
83             return;
84         }
85         mContext.registerReceiver(mBluetoothChangedReceiver,
86                 new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
87         mAlwaysDiscoverable.start();
88         updateFooterPreferenceTitle(mBluetoothAdapter.getState());
89     }
90 
91     @Override
onStop()92     public void onStop() {
93         if (mLocalManager == null) {
94             return;
95         }
96         mContext.unregisterReceiver(mBluetoothChangedReceiver);
97         mAlwaysDiscoverable.stop();
98     }
99 
updateFooterPreferenceTitle(int bluetoothState)100     private void updateFooterPreferenceTitle(int bluetoothState) {
101         if (bluetoothState == BluetoothAdapter.STATE_ON) {
102             mPreference.setTitle(getPreferenceTitle());
103         } else {
104             mPreference.setTitle(R.string.bluetooth_off_footer);
105         }
106     }
107 
getPreferenceTitle()108     private CharSequence getPreferenceTitle() {
109         final String deviceName = mBluetoothAdapter.getName();
110         if (TextUtils.isEmpty(deviceName)) {
111             return null;
112         }
113 
114         return TextUtils.expandTemplate(
115                 mContext.getText(R.string.bluetooth_device_name_summary),
116                 BidiFormatter.getInstance().unicodeWrap(deviceName));
117     }
118 
initReceiver()119     private void initReceiver() {
120         mBluetoothChangedReceiver = new BroadcastReceiver() {
121             @Override
122             public void onReceive(Context context, Intent intent) {
123                 if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
124                     final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
125                             BluetoothAdapter.ERROR);
126                     updateFooterPreferenceTitle(state);
127                 }
128             }
129         };
130     }
131 }