BluetoothTile.java revision 64fe15846c541950b574bfb681efb8a794183ff6
1/*
2 * Copyright (C) 2014 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
17package com.android.systemui.qs.tiles;
18
19import android.content.Context;
20import android.content.Intent;
21import android.provider.Settings;
22import android.text.TextUtils;
23import android.view.View;
24import android.view.ViewGroup;
25
26import com.android.systemui.R;
27import com.android.systemui.qs.QSDetailItems;
28import com.android.systemui.qs.QSDetailItems.Item;
29import com.android.systemui.qs.QSTile;
30import com.android.systemui.statusbar.policy.BluetoothController;
31import com.android.systemui.statusbar.policy.BluetoothController.PairedDevice;
32
33import java.util.Set;
34
35/** Quick settings tile: Bluetooth **/
36public class BluetoothTile extends QSTile<QSTile.BooleanState>  {
37    private static final Intent BLUETOOTH_SETTINGS = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
38
39    private final BluetoothController mController;
40    private final BluetoothDetailAdapter mDetailAdapter;
41
42    public BluetoothTile(Host host) {
43        super(host);
44        mController = host.getBluetoothController();
45        mDetailAdapter = new BluetoothDetailAdapter();
46    }
47
48    @Override
49    public boolean supportsDualTargets() {
50        return true;
51    }
52
53    @Override
54    public DetailAdapter getDetailAdapter() {
55        return mDetailAdapter;
56    }
57
58    @Override
59    protected BooleanState newTileState() {
60        return new BooleanState();
61    }
62
63    @Override
64    public void setListening(boolean listening) {
65        if (listening) {
66            mController.addStateChangedCallback(mCallback);
67        } else {
68            mController.removeStateChangedCallback(mCallback);
69        }
70    }
71
72    @Override
73    protected void handleClick() {
74        final boolean isEnabled = (Boolean)mState.value;
75        mController.setBluetoothEnabled(!isEnabled);
76    }
77
78    @Override
79    protected void handleSecondaryClick() {
80        showDetail(true);
81    }
82
83    @Override
84    protected void handleUpdateState(BooleanState state, Object arg) {
85        final boolean supported = mController.isBluetoothSupported();
86        final boolean enabled = mController.isBluetoothEnabled();
87        final boolean connected = mController.isBluetoothConnected();
88        final boolean connecting = mController.isBluetoothConnecting();
89        state.visible = supported;
90        state.value = enabled;
91        final String stateContentDescription;
92        if (enabled) {
93            state.label = null;
94            if (connected) {
95                state.iconId = R.drawable.ic_qs_bluetooth_connected;
96                stateContentDescription = mContext.getString(R.string.accessibility_desc_connected);
97                state.label = mController.getLastDeviceName();
98            } else if (connecting) {
99                state.iconId = R.drawable.ic_qs_bluetooth_connecting;
100                stateContentDescription =
101                        mContext.getString(R.string.accessibility_desc_connecting);
102                state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
103            } else {
104                state.iconId = R.drawable.ic_qs_bluetooth_on;
105                stateContentDescription = mContext.getString(R.string.accessibility_desc_on);
106            }
107            if (TextUtils.isEmpty(state.label)) {
108                state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
109            }
110        } else {
111            state.iconId = R.drawable.ic_qs_bluetooth_off;
112            state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
113            stateContentDescription = mContext.getString(R.string.accessibility_desc_off);
114        }
115        state.contentDescription = mContext.getString(
116                R.string.accessibility_quick_settings_bluetooth, stateContentDescription);
117    }
118
119    private final BluetoothController.Callback mCallback = new BluetoothController.Callback() {
120        @Override
121        public void onBluetoothStateChange(boolean enabled, boolean connecting) {
122            refreshState();
123        }
124        @Override
125        public void onBluetoothPairedDevicesChanged() {
126            mUiHandler.post(new Runnable() {
127                @Override
128                public void run() {
129                    mDetailAdapter.updateItems();
130                }
131            });
132        }
133    };
134
135    private final class BluetoothDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
136        private QSDetailItems mItems;
137
138        @Override
139        public int getTitle() {
140            return R.string.quick_settings_bluetooth_label;
141        }
142
143        @Override
144        public Boolean getToggleState() {
145            return mState.value;
146        }
147
148        @Override
149        public Intent getSettingsIntent() {
150            return BLUETOOTH_SETTINGS;
151        }
152
153        @Override
154        public void setToggleState(boolean state) {
155            mController.setBluetoothEnabled(state);
156            showDetail(false);
157        }
158
159        @Override
160        public View createDetailView(Context context, View convertView, ViewGroup parent) {
161            mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
162            mItems.setTagSuffix("Bluetooth");
163            mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
164                    R.string.quick_settings_bluetooth_detail_empty_text);
165            mItems.setCallback(this);
166            updateItems();
167            setItemsVisible(mState.value);
168            return mItems;
169        }
170
171        public void setItemsVisible(boolean visible) {
172            if (mItems == null) return;
173            mItems.setItemsVisible(visible);
174        }
175
176        private void updateItems() {
177            if (mItems == null) return;
178            Item[] items = null;
179            final Set<PairedDevice> devices = mController.getPairedDevices();
180            if (devices != null) {
181                items = new Item[devices.size()];
182                int i = 0;
183                for (PairedDevice device : devices) {
184                    final Item item = new Item();
185                    item.icon = R.drawable.ic_qs_bluetooth_on;
186                    item.line1 = device.name;
187                    if (device.state == PairedDevice.STATE_CONNECTED) {
188                        item.icon = R.drawable.ic_qs_bluetooth_connected;
189                        item.line2 = mContext.getString(R.string.quick_settings_connected);
190                        item.canDisconnect = true;
191                    } else if (device.state == PairedDevice.STATE_CONNECTING) {
192                        item.icon = R.drawable.ic_qs_bluetooth_connecting;
193                        item.line2 = mContext.getString(R.string.quick_settings_connecting);
194                    }
195                    item.tag = device;
196                    items[i++] = item;
197                }
198            }
199            mItems.setItems(items);
200        }
201
202        @Override
203        public void onDetailItemClick(Item item) {
204            if (item == null || item.tag == null) return;
205            final PairedDevice device = (PairedDevice) item.tag;
206            if (device != null && device.state == PairedDevice.STATE_DISCONNECTED) {
207                mController.connect(device);
208            }
209        }
210
211        @Override
212        public void onDetailItemDisconnect(Item item) {
213            if (item == null || item.tag == null) return;
214            final PairedDevice device = (PairedDevice) item.tag;
215            if (device != null) {
216                mController.disconnect(device);
217            }
218        }
219    }
220}
221