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.support.v7.preference.PreferenceScreen; 26 import android.text.BidiFormatter; 27 import android.text.TextUtils; 28 29 import com.android.internal.annotations.VisibleForTesting; 30 import com.android.settings.bluetooth.AlwaysDiscoverable; 31 import com.android.settings.bluetooth.Utils; 32 import com.android.settings.core.BasePreferenceController; 33 import com.android.settings.dashboard.DashboardFragment; 34 import com.android.settings.R; 35 import com.android.settingslib.bluetooth.LocalBluetoothAdapter; 36 import com.android.settingslib.bluetooth.LocalBluetoothManager; 37 import com.android.settingslib.core.lifecycle.events.OnPause; 38 import com.android.settingslib.core.lifecycle.events.OnResume; 39 import com.android.settingslib.core.lifecycle.LifecycleObserver; 40 import com.android.settingslib.widget.FooterPreference; 41 import com.android.settingslib.widget.FooterPreferenceMixin; 42 43 /** 44 * Controller that shows and updates the bluetooth device name 45 */ 46 public class DiscoverableFooterPreferenceController extends BasePreferenceController 47 implements LifecycleObserver, OnResume, OnPause { 48 private static final String KEY = "discoverable_footer_preference"; 49 50 @VisibleForTesting 51 BroadcastReceiver mBluetoothChangedReceiver; 52 private FooterPreferenceMixin mFooterPreferenceMixin; 53 private FooterPreference mPreference; 54 private LocalBluetoothManager mLocalManager; 55 private LocalBluetoothAdapter mLocalAdapter; 56 private AlwaysDiscoverable mAlwaysDiscoverable; 57 58 public DiscoverableFooterPreferenceController(Context context) { 59 super(context, KEY); 60 mLocalManager = Utils.getLocalBtManager(context); 61 if (mLocalManager == null) { 62 return; 63 } 64 mLocalAdapter = mLocalManager.getBluetoothAdapter(); 65 mAlwaysDiscoverable = new AlwaysDiscoverable(context, mLocalAdapter); 66 initReceiver(); 67 } 68 69 private void initReceiver() { 70 mBluetoothChangedReceiver = new BroadcastReceiver() { 71 @Override 72 public void onReceive(Context context, Intent intent) { 73 if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 74 final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 75 BluetoothAdapter.ERROR); 76 updateFooterPreferenceTitle(state); 77 } 78 } 79 }; 80 } 81 82 public void init(DashboardFragment fragment) { 83 mFooterPreferenceMixin = new FooterPreferenceMixin(fragment, fragment.getLifecycle()); 84 } 85 86 @VisibleForTesting 87 void init(FooterPreferenceMixin footerPreferenceMixin, FooterPreference preference, 88 AlwaysDiscoverable alwaysDiscoverable) { 89 mFooterPreferenceMixin = footerPreferenceMixin; 90 mPreference = preference; 91 mAlwaysDiscoverable = alwaysDiscoverable; 92 } 93 94 @Override 95 public void displayPreference(PreferenceScreen screen) { 96 super.displayPreference(screen); 97 addFooterPreference(screen); 98 } 99 100 @Override 101 public int getAvailabilityStatus() { 102 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH) 103 ? AVAILABLE 104 : UNSUPPORTED_ON_DEVICE; 105 } 106 107 private void addFooterPreference(PreferenceScreen screen) { 108 mPreference = mFooterPreferenceMixin.createFooterPreference(); 109 mPreference.setKey(KEY); 110 screen.addPreference(mPreference); 111 } 112 113 @Override 114 public void onResume() { 115 mContext.registerReceiver(mBluetoothChangedReceiver, 116 new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); 117 mAlwaysDiscoverable.start(); 118 updateFooterPreferenceTitle(mLocalAdapter.getState()); 119 } 120 121 @Override 122 public void onPause() { 123 mContext.unregisterReceiver(mBluetoothChangedReceiver); 124 mAlwaysDiscoverable.stop(); 125 } 126 127 private void updateFooterPreferenceTitle (int bluetoothState) { 128 if (bluetoothState == BluetoothAdapter.STATE_ON) { 129 mPreference.setTitle(getPreferenceTitle()); 130 } else { 131 mPreference.setTitle(R.string.bluetooth_off_footer); 132 } 133 } 134 135 private CharSequence getPreferenceTitle() { 136 final String deviceName = mLocalAdapter.getName(); 137 if (TextUtils.isEmpty(deviceName)) { 138 return null; 139 } 140 141 return TextUtils.expandTemplate( 142 mContext.getText(R.string.bluetooth_device_name_summary), 143 BidiFormatter.getInstance().unicodeWrap(deviceName)); 144 } 145 }