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