1/*
2 * Copyright (C) 2008 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.statusbar.policy;
18
19import android.bluetooth.BluetoothAdapter;
20import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
21import android.bluetooth.BluetoothDevice;
22import android.content.BroadcastReceiver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.IntentFilter;
26import android.view.View;
27import android.widget.ImageView;
28
29import com.android.systemui.R;
30
31import java.util.ArrayList;
32import java.util.HashSet;
33import java.util.Set;
34
35public class BluetoothController extends BroadcastReceiver {
36    private static final String TAG = "StatusBar.BluetoothController";
37
38    private Context mContext;
39    private ArrayList<ImageView> mIconViews = new ArrayList<ImageView>();
40
41    private int mIconId = R.drawable.stat_sys_data_bluetooth;
42    private int mContentDescriptionId = 0;
43    private boolean mEnabled = false;
44
45    private Set<BluetoothDevice> mBondedDevices = new HashSet<BluetoothDevice>();
46
47    private ArrayList<BluetoothStateChangeCallback> mChangeCallbacks =
48            new ArrayList<BluetoothStateChangeCallback>();
49
50    public BluetoothController(Context context) {
51        mContext = context;
52
53        IntentFilter filter = new IntentFilter();
54        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
55        filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
56        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
57        context.registerReceiver(this, filter);
58
59        final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
60        if (adapter != null) {
61            handleAdapterStateChange(adapter.getState());
62            handleConnectionStateChange(adapter.getConnectionState());
63        }
64        refreshViews();
65        updateBondedBluetoothDevices();
66    }
67
68    public void addIconView(ImageView v) {
69        mIconViews.add(v);
70    }
71
72    public void addStateChangedCallback(BluetoothStateChangeCallback cb) {
73        mChangeCallbacks.add(cb);
74    }
75
76    public Set<BluetoothDevice> getBondedBluetoothDevices() {
77        return mBondedDevices;
78    }
79
80    @Override
81    public void onReceive(Context context, Intent intent) {
82        final String action = intent.getAction();
83
84        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
85            handleAdapterStateChange(
86                    intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR));
87        } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
88            handleConnectionStateChange(
89                    intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
90                        BluetoothAdapter.STATE_DISCONNECTED));
91        } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
92            // Fall through and update bonded devices and refresh view
93        }
94        refreshViews();
95        updateBondedBluetoothDevices();
96    }
97
98    private void updateBondedBluetoothDevices() {
99        mBondedDevices.clear();
100
101        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
102        if (adapter != null) {
103            Set<BluetoothDevice> devices = adapter.getBondedDevices();
104            if (devices != null) {
105                for (BluetoothDevice device : devices) {
106                    if (device.getBondState() != BluetoothDevice.BOND_NONE) {
107                        mBondedDevices.add(device);
108                    }
109                }
110            }
111        }
112    }
113
114    public void handleAdapterStateChange(int adapterState) {
115        mEnabled = (adapterState == BluetoothAdapter.STATE_ON);
116    }
117
118    public void handleConnectionStateChange(int connectionState) {
119        final boolean connected = (connectionState == BluetoothAdapter.STATE_CONNECTED);
120        if (connected) {
121            mIconId = R.drawable.stat_sys_data_bluetooth_connected;
122            mContentDescriptionId = R.string.accessibility_bluetooth_connected;
123        } else {
124            mIconId = R.drawable.stat_sys_data_bluetooth;
125            mContentDescriptionId = R.string.accessibility_bluetooth_disconnected;
126        }
127    }
128
129    public void refreshViews() {
130        int N = mIconViews.size();
131        for (int i=0; i<N; i++) {
132            ImageView v = mIconViews.get(i);
133            v.setImageResource(mIconId);
134            v.setVisibility(mEnabled ? View.VISIBLE : View.GONE);
135            v.setContentDescription((mContentDescriptionId == 0)
136                    ? null
137                    : mContext.getString(mContentDescriptionId));
138        }
139        for (BluetoothStateChangeCallback cb : mChangeCallbacks) {
140            cb.onBluetoothStateChange(mEnabled);
141        }
142    }
143}
144