1 /*
2  * Copyright (C) 2017 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.settings.network.SatelliteWarningDialogActivity.EXTRA_TYPE_OF_SATELLITE_WARNING_DIALOG;
20 import static com.android.settings.network.SatelliteWarningDialogActivity.TYPE_IS_BLUETOOTH;
21 
22 import android.app.settings.SettingsEnums;
23 import android.bluetooth.BluetoothAdapter;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.os.Bundle;
27 import android.util.Log;
28 import android.view.View;
29 
30 import androidx.annotation.NonNull;
31 import androidx.annotation.Nullable;
32 import androidx.annotation.VisibleForTesting;
33 
34 import com.android.settings.R;
35 import com.android.settings.network.SatelliteRepository;
36 import com.android.settings.network.SatelliteWarningDialogActivity;
37 import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
38 import com.android.settingslib.search.Indexable;
39 import com.android.settingslib.widget.FooterPreference;
40 
41 import java.util.concurrent.ExecutionException;
42 import java.util.concurrent.Executors;
43 import java.util.concurrent.TimeUnit;
44 import java.util.concurrent.TimeoutException;
45 
46 /**
47  * BluetoothPairingDetail is a page to scan bluetooth devices and pair them.
48  */
49 public class BluetoothPairingDetail extends BluetoothDevicePairingDetailBase implements
50         Indexable {
51     private static final String TAG = "BluetoothPairingDetail";
52 
53     @VisibleForTesting
54     static final String KEY_AVAIL_DEVICES = "available_devices";
55     @VisibleForTesting
56     static final String KEY_FOOTER_PREF = "footer_preference";
57 
58     @VisibleForTesting
59     FooterPreference mFooterPreference;
60     @VisibleForTesting
61     AlwaysDiscoverable mAlwaysDiscoverable;
62 
BluetoothPairingDetail()63     public BluetoothPairingDetail() {
64         super();
65     }
66 
67     @Override
onAttach(Context context)68     public void onAttach(Context context) {
69         super.onAttach(context);
70         if (mayStartSatelliteWarningDialog()) {
71             finish();
72             return;
73         }
74         use(BluetoothDeviceRenamePreferenceController.class).setFragment(this);
75     }
76 
mayStartSatelliteWarningDialog()77     private boolean mayStartSatelliteWarningDialog() {
78         SatelliteRepository satelliteRepository = new SatelliteRepository(this.getContext());
79         boolean isSatelliteOn = true;
80         try {
81             isSatelliteOn =
82                     satelliteRepository.requestIsEnabled(
83                             Executors.newSingleThreadExecutor()).get(3000, TimeUnit.MILLISECONDS);
84         } catch (InterruptedException | ExecutionException | TimeoutException e) {
85             Log.e(TAG, "Error to get satellite status : " + e);
86         }
87         if (!isSatelliteOn) {
88             return false;
89         }
90         startActivity(
91                 new Intent(getContext(), SatelliteWarningDialogActivity.class)
92                         .putExtra(
93                                 EXTRA_TYPE_OF_SATELLITE_WARNING_DIALOG,
94                                 TYPE_IS_BLUETOOTH)
95         );
96         return true;
97     }
98 
99     @Override
onViewCreated(@onNull View view, @Nullable Bundle savedInstanceState)100     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
101         super.onViewCreated(view, savedInstanceState);
102         mAlwaysDiscoverable = new AlwaysDiscoverable(getContext());
103     }
104 
105     @Override
onStart()106     public void onStart() {
107         super.onStart();
108         mAvailableDevicesCategory.setProgress(mBluetoothAdapter.isDiscovering());
109     }
110 
111     @Override
onStop()112     public void onStop() {
113         super.onStop();
114         // Make the device only visible to connected devices.
115         mAlwaysDiscoverable.stop();
116     }
117 
118     @Override
initPreferencesFromPreferenceScreen()119     public void initPreferencesFromPreferenceScreen() {
120         super.initPreferencesFromPreferenceScreen();
121         mFooterPreference = findPreference(KEY_FOOTER_PREF);
122         mFooterPreference.setSelectable(false);
123     }
124 
125     @Override
getMetricsCategory()126     public int getMetricsCategory() {
127         return SettingsEnums.BLUETOOTH_PAIRING;
128     }
129 
130     /**
131      * {@inheritDoc}
132      *
133      * Will update footer and keep the device discoverable as long as the page is visible.
134      */
135     @VisibleForTesting
136     @Override
updateContent(int bluetoothState)137     public void updateContent(int bluetoothState) {
138         super.updateContent(bluetoothState);
139         if (bluetoothState == BluetoothAdapter.STATE_ON) {
140             if (mInitialScanStarted) {
141                 // Don't show bonded devices when screen turned back on
142                 addCachedDevices(BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER);
143             }
144             updateFooterPreference(mFooterPreference);
145             mAlwaysDiscoverable.start();
146         }
147     }
148 
149     @Override
onScanningStateChanged(boolean started)150     public void onScanningStateChanged(boolean started) {
151         super.onScanningStateChanged(started);
152         started |= mScanEnabled;
153         mAvailableDevicesCategory.setProgress(started);
154     }
155 
156     @Override
getHelpResource()157     public int getHelpResource() {
158         return R.string.help_url_bluetooth;
159     }
160 
161     @Override
getLogTag()162     protected String getLogTag() {
163         return TAG;
164     }
165 
166     @Override
getPreferenceScreenResId()167     protected int getPreferenceScreenResId() {
168         return R.xml.bluetooth_pairing_detail;
169     }
170 
171     @Override
getDeviceListKey()172     public String getDeviceListKey() {
173         return KEY_AVAIL_DEVICES;
174     }
175 }
176