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.car.settings.quicksettings; 18 19 import android.annotation.DrawableRes; 20 import android.annotation.Nullable; 21 import android.bluetooth.BluetoothAdapter; 22 import android.content.BroadcastReceiver; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.IntentFilter; 26 import android.graphics.drawable.Drawable; 27 import android.view.View; 28 29 import com.android.car.settings.R; 30 import com.android.car.settings.common.CarSettingActivities; 31 import com.android.car.settings.common.FragmentHost; 32 import com.android.car.settings.common.Logger; 33 34 /** 35 * Controls Bluetooth tile on quick setting page. 36 */ 37 public class BluetoothTile implements QuickSettingGridAdapter.Tile { 38 private static final Logger LOG = new Logger(BluetoothTile.class); 39 private final Context mContext; 40 private final StateChangedListener mStateChangedListener; 41 private BluetoothAdapter mBluetoothAdapter; 42 private View.OnLongClickListener mLaunchBluetoothSettings; 43 44 @DrawableRes 45 private int mIconRes = R.drawable.ic_settings_bluetooth; 46 47 private String mText; 48 49 private State mState = State.OFF; 50 51 private final BroadcastReceiver mBtStateReceiver = new BroadcastReceiver() { 52 @Override 53 public void onReceive(Context context, Intent intent) { 54 String action = intent.getAction(); 55 56 if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 57 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 58 BluetoothAdapter.ERROR); 59 switch (state) { 60 case BluetoothAdapter.STATE_TURNING_OFF: 61 // TODO show a different status icon? 62 case BluetoothAdapter.STATE_OFF: 63 mIconRes = R.drawable.ic_settings_bluetooth_disabled; 64 mState = State.OFF; 65 break; 66 default: 67 mIconRes = R.drawable.ic_settings_bluetooth; 68 mText = mContext.getString(R.string.bluetooth_settings_title); 69 mState = State.ON; 70 } 71 } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { 72 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, 73 BluetoothAdapter.ERROR); 74 switch (state) { 75 case BluetoothAdapter.STATE_CONNECTED: 76 mIconRes = R.drawable.ic_settings_bluetooth_connected; 77 break; 78 case BluetoothAdapter.STATE_DISCONNECTED: 79 default: 80 mIconRes = R.drawable.ic_settings_bluetooth; 81 } 82 } 83 mStateChangedListener.onStateChanged(); 84 } 85 }; 86 BluetoothTile( Context context, StateChangedListener stateChangedListener, FragmentHost fragmentHost)87 BluetoothTile( 88 Context context, 89 StateChangedListener stateChangedListener, 90 FragmentHost fragmentHost) { 91 mStateChangedListener = stateChangedListener; 92 mContext = context; 93 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 94 if (mBluetoothAdapter == null) { 95 LOG.e("Bluetooth is not supported on this device"); 96 return; 97 } 98 mText = mContext.getString(R.string.bluetooth_settings_title); 99 mLaunchBluetoothSettings = v -> { 100 context.startActivity(new Intent(context, 101 CarSettingActivities.BluetoothSettingsActivity.class)); 102 return true; 103 }; 104 } 105 106 @Nullable getOnLongClickListener()107 public View.OnLongClickListener getOnLongClickListener() { 108 return mLaunchBluetoothSettings; 109 } 110 111 @Override isAvailable()112 public boolean isAvailable() { 113 return mBluetoothAdapter != null; 114 } 115 116 @Override getIcon()117 public Drawable getIcon() { 118 return mContext.getDrawable(mIconRes); 119 } 120 121 @Override 122 @Nullable getText()123 public String getText() { 124 // TODO: return connected ssid 125 return mText; 126 } 127 128 @Override getState()129 public State getState() { 130 return mState; 131 } 132 133 @Override start()134 public void start() { 135 IntentFilter mBtStateChangeFilter = new IntentFilter(); 136 mBtStateChangeFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 137 mBtStateChangeFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); 138 mContext.registerReceiver(mBtStateReceiver, mBtStateChangeFilter); 139 updateBluetoothIconState(); 140 } 141 142 @Override stop()143 public void stop() { 144 mContext.unregisterReceiver(mBtStateReceiver); 145 } 146 147 @Override onClick(View v)148 public void onClick(View v) { 149 if (mBluetoothAdapter == null) { 150 return; 151 } 152 if (mBluetoothAdapter.isEnabled()) { 153 mBluetoothAdapter.disable(); 154 } else { 155 mBluetoothAdapter.enable(); 156 } 157 } 158 updateBluetoothIconState()159 private void updateBluetoothIconState() { 160 if (mBluetoothAdapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED) { 161 mIconRes = R.drawable.ic_settings_bluetooth_connected; 162 mState = State.ON; 163 } else if (mBluetoothAdapter.isEnabled()) { 164 mIconRes = R.drawable.ic_settings_bluetooth; 165 mState = State.ON; 166 } else { 167 mIconRes = R.drawable.ic_settings_bluetooth_disabled; 168 mState = State.OFF; 169 } 170 171 mStateChangedListener.onStateChanged(); 172 } 173 } 174