blob: b4a9d760cbe429c29c2557812aa05ed58a0e5e6e [file] [log] [blame]
Daniel Sandler6425ef92010-08-11 16:10:19 -04001/*
2 * Copyright (C) 2010 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.tablet;
18
19import android.app.Notification;
20import android.app.PendingIntent;
21import android.app.Service;
22import android.app.StatusBarManager;
Daniel Sandlerd39e3882010-08-31 14:16:13 -040023import android.bluetooth.BluetoothAdapter;
Daniel Sandler6425ef92010-08-11 16:10:19 -040024import android.content.BroadcastReceiver;
25import android.content.ContentResolver;
26import android.content.Context;
27import android.content.Intent;
28import android.content.IntentFilter;
29import android.content.res.Resources;
30import android.graphics.PixelFormat;
31import android.graphics.Rect;
Daniel Sandlerd39e3882010-08-31 14:16:13 -040032import android.location.LocationManager;
Daniel Sandler6425ef92010-08-11 16:10:19 -040033import android.media.AudioManager;
Daniel Sandlerd7db7b12010-08-13 16:26:39 -040034import android.net.NetworkInfo;
35import android.net.wifi.SupplicantState;
36import android.net.wifi.WifiConfiguration;
37import android.net.wifi.WifiInfo;
38import android.net.wifi.WifiManager;
Daniel Sandler6425ef92010-08-11 16:10:19 -040039import android.os.AsyncTask;
40import android.os.Handler;
41import android.os.IBinder;
42import android.os.IPowerManager;
43import android.os.Message;
44import android.os.RemoteException;
45import android.os.RemoteException;
46import android.os.ServiceManager;
47import android.provider.Settings;
48import android.telephony.PhoneStateListener;
49import android.telephony.ServiceState;
Daniel Sandler764b4da2010-08-24 16:24:35 -040050import android.telephony.SignalStrength;
Daniel Sandler6425ef92010-08-11 16:10:19 -040051import android.telephony.TelephonyManager;
52import android.util.AttributeSet;
53import android.util.Slog;
54import android.view.Gravity;
55import android.view.LayoutInflater;
56import android.view.View;
57import android.view.ViewGroup;
Daniel Sandlerb73617d2010-08-17 00:41:00 -040058import android.view.IWindowManager;
Daniel Sandler6425ef92010-08-11 16:10:19 -040059import android.view.WindowManager;
60import android.view.WindowManagerImpl;
61import android.widget.Button;
62import android.widget.ImageButton;
63import android.widget.ImageView;
64import android.widget.LinearLayout;
65import android.widget.RemoteViews;
66import android.widget.ScrollView;
67import android.widget.TextSwitcher;
68import android.widget.TextView;
69import android.widget.Toast;
70
Daniel Sandlerd7db7b12010-08-13 16:26:39 -040071import java.util.List;
72
Daniel Sandler764b4da2010-08-24 16:24:35 -040073import com.android.internal.telephony.IccCard;
74import com.android.internal.telephony.TelephonyIntents;
75import com.android.internal.telephony.cdma.EriInfo;
76import com.android.internal.telephony.cdma.TtyIntent;
77
Daniel Sandlerb73617d2010-08-17 00:41:00 -040078import com.android.server.WindowManagerService;
79
Daniel Sandler6425ef92010-08-11 16:10:19 -040080import com.android.systemui.statusbar.*;
81import com.android.systemui.R;
82
Joe Onoratoddf680b2010-09-26 13:59:40 -070083public class SystemPanel extends LinearLayout implements StatusBarPanel {
Daniel Sandler6425ef92010-08-11 16:10:19 -040084 private static final String TAG = "SystemPanel";
Daniel Sandler764b4da2010-08-24 16:24:35 -040085 private static final boolean DEBUG = TabletStatusBarService.DEBUG;
Daniel Sandler63cbc4c2010-08-27 14:34:15 -040086 private static final boolean DEBUG_SIGNAL = false;
Daniel Sandler6425ef92010-08-11 16:10:19 -040087
88 private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 5;
89 private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
90 private static final int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f);
91
Daniel Sandler6425ef92010-08-11 16:10:19 -040092 private TabletStatusBarService mBar;
93 private boolean mAirplaneMode;
94
95 private ImageButton mBrightnessButton;
96 private ImageButton mSoundButton;
97 private ImageButton mOrientationButton;
98 private ImageButton mAirplaneButton;
Daniel Sandlerd39e3882010-08-31 14:16:13 -040099 private ImageButton mGpsButton;
100 private ImageButton mBluetoothButton;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400101
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400102 private ImageView mBatteryMeter;
103 private ImageView mSignalMeter;
104
105 private TextView mBatteryText;
106 private TextView mSignalText;
107
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400108 private final IWindowManager mWM;
109
Daniel Sandler6425ef92010-08-11 16:10:19 -0400110 private final AudioManager mAudioManager;
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400111 private final WifiManager mWifiManager;
Daniel Sandler764b4da2010-08-24 16:24:35 -0400112 private final TelephonyManager mPhone;
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400113 private final BluetoothAdapter mBluetoothAdapter;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400114
Daniel Sandler764b4da2010-08-24 16:24:35 -0400115 // state trackers for telephony code
116 IccCard.State mSimState = IccCard.State.READY;
117 int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
118 int mDataState = TelephonyManager.DATA_DISCONNECTED;
119 ServiceState mServiceState;
120 SignalStrength mSignalStrength;
121
122 // state for the meters
123 boolean mWifiEnabled, mWifiConnected;
124 int mWifiLevel;
125 String mWifiSsid;
126
127 boolean mDataEnabled, mDataConnected, mDataRoaming;
128 int mDataLevel;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400129
Joe Onoratoddf680b2010-09-26 13:59:40 -0700130 public boolean isInContentArea(int x, int y) {
131 final int l = getPaddingLeft();
132 final int r = getWidth() - getPaddingRight();
133 final int t = getPaddingTop();
134 final int b = getHeight() - getPaddingBottom();
135 return x >= l && x < r && y >= t && y < b;
136 }
137
Daniel Sandler6425ef92010-08-11 16:10:19 -0400138 private BroadcastReceiver mReceiver = new BroadcastReceiver() {
139 @Override
140 public void onReceive(Context context, Intent intent) {
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400141 final String action = intent.getAction();
142 if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400143 refreshSound();
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400144 } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400145 updateBattery(intent);
146 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
147 || action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)
148 || action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)
149 || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
Daniel Sandler764b4da2010-08-24 16:24:35 -0400150 updateWifiState(intent);
151 } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
152 updateSimState(intent);
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400153 } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
154 refreshBluetooth();
Daniel Sandler6425ef92010-08-11 16:10:19 -0400155 }
156 }
157 };
158
Daniel Sandler764b4da2010-08-24 16:24:35 -0400159 private final void updateSimState(Intent intent) {
160 String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
161 if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
162 mSimState = IccCard.State.ABSENT;
163 }
164 else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
165 mSimState = IccCard.State.READY;
166 }
167 else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
168 final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
169 if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
170 mSimState = IccCard.State.PIN_REQUIRED;
171 }
172 else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
173 mSimState = IccCard.State.PUK_REQUIRED;
174 }
175 else {
176 mSimState = IccCard.State.NETWORK_LOCKED;
177 }
178 } else {
179 mSimState = IccCard.State.UNKNOWN;
180 }
181 updateDataState();
182 }
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400183
Daniel Sandler764b4da2010-08-24 16:24:35 -0400184 private boolean isCdma() {
185 return (mSignalStrength != null) && !mSignalStrength.isGsm();
186 }
187
188 private boolean isEvdo() {
189 return ( (mServiceState != null)
190 && ((mServiceState.getRadioTechnology()
191 == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
192 || (mServiceState.getRadioTechnology()
193 == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
194 || (mServiceState.getRadioTechnology()
195 == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
196 }
197
198 private boolean hasService() {
199 if (mServiceState != null) {
200 switch (mServiceState.getState()) {
201 case ServiceState.STATE_OUT_OF_SERVICE:
202 case ServiceState.STATE_POWER_OFF:
203 return false;
204 default:
205 return true;
206 }
207 } else {
208 return false;
209 }
210 }
211
212 private int getCdmaLevel() {
213 if (mSignalStrength == null) return 0;
214 final int cdmaDbm = mSignalStrength.getCdmaDbm();
215 final int cdmaEcio = mSignalStrength.getCdmaEcio();
216 int levelDbm = 0;
217 int levelEcio = 0;
218
219 if (cdmaDbm >= -75) levelDbm = 4;
220 else if (cdmaDbm >= -85) levelDbm = 3;
221 else if (cdmaDbm >= -95) levelDbm = 2;
222 else if (cdmaDbm >= -100) levelDbm = 1;
223 else levelDbm = 0;
224
225 // Ec/Io are in dB*10
226 if (cdmaEcio >= -90) levelEcio = 4;
227 else if (cdmaEcio >= -110) levelEcio = 3;
228 else if (cdmaEcio >= -130) levelEcio = 2;
229 else if (cdmaEcio >= -150) levelEcio = 1;
230 else levelEcio = 0;
231
232 return (levelDbm < levelEcio) ? levelDbm : levelEcio;
233 }
234
235 private int getEvdoLevel() {
236 if (mSignalStrength == null) return 0;
237 int evdoDbm = mSignalStrength.getEvdoDbm();
238 int evdoSnr = mSignalStrength.getEvdoSnr();
239 int levelEvdoDbm = 0;
240 int levelEvdoSnr = 0;
241
242 if (evdoDbm >= -65) levelEvdoDbm = 4;
243 else if (evdoDbm >= -75) levelEvdoDbm = 3;
244 else if (evdoDbm >= -90) levelEvdoDbm = 2;
245 else if (evdoDbm >= -105) levelEvdoDbm = 1;
246 else levelEvdoDbm = 0;
247
248 if (evdoSnr >= 7) levelEvdoSnr = 4;
249 else if (evdoSnr >= 5) levelEvdoSnr = 3;
250 else if (evdoSnr >= 3) levelEvdoSnr = 2;
251 else if (evdoSnr >= 1) levelEvdoSnr = 1;
252 else levelEvdoSnr = 0;
253
254 return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
255 }
256
257 private void updateDataState() {
258 mDataConnected = hasService() && (mDataState == TelephonyManager.DATA_CONNECTED);
259
260 if (isCdma()) {
261 // these functions return a value from 0 to 4, inclusive
262 if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
263 mDataLevel = getEvdoLevel() * 25;
264 } else {
265 mDataLevel = getCdmaLevel() * 25;
266 }
267 } else {
268 // GSM
269
270 int asu = (mSignalStrength == null) ? 0 : mSignalStrength.getGsmSignalStrength();
271
272 // asu on [0,31]; 99 = unknown
273 // Android has historically shown anything >=12 as "full"
274 // XXX: tune this based on Industry Best Practices(TM)
275 if (asu <= 2 || asu == 99) mDataLevel = 0;
276 else mDataLevel = (int)(((float)Math.max(asu, 15) / 15) * 100);
277
278 mDataRoaming = mPhone.isNetworkRoaming();
279
280 mDataConnected = mDataConnected
281 && (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN);
282 }
283
284 if (DEBUG_SIGNAL || DEBUG) {
285 Slog.d(TAG, "updateDataState: connected=" + mDataConnected
286 + " level=" + mDataLevel
287 + " isEvdo=" + isEvdo()
288 + " isCdma=" + isCdma()
289 + " mPhoneState=" + mPhoneState
290 + " mDataState=" + mDataState
291 );
292 }
293
294 refreshSignalMeters();
295 }
296
297 private void updateWifiState(Intent intent) {
298 if (DEBUG)
299 Slog.d(TAG, "updateWifiState: " + intent);
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400300
301 final String action = intent.getAction();
302 final boolean wasConnected = mWifiConnected;
303
304 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
305 mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
306 WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
307 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
308 final NetworkInfo networkInfo = (NetworkInfo)
309 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
310 mWifiConnected = networkInfo != null && networkInfo.isConnected();
311 } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
312 final NetworkInfo.DetailedState detailedState = WifiInfo.getDetailedStateOf(
313 (SupplicantState)intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE));
314 mWifiConnected = detailedState == NetworkInfo.DetailedState.CONNECTED;
315 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
316 final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400317 int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 101);
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400318 mWifiLevel = mWifiConnected ? newSignalLevel : 0;
319 }
320
321 if (mWifiConnected && !wasConnected) {
322 WifiInfo info = mWifiManager.getConnectionInfo();
Daniel Sandler764b4da2010-08-24 16:24:35 -0400323 if (DEBUG)
324 Slog.d(TAG, "updateWifiState: just connected: info=" + info);
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400325
326 if (info != null) {
327 // grab the initial signal strength
328 mWifiLevel = WifiManager.calculateSignalLevel(info.getRssi(), 101);
329
330 // find the SSID
331 mWifiSsid = info.getSSID();
332 if (mWifiSsid == null) {
333 // OK, it's not in the connectionInfo; we have to go hunting for it
334 List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
335 for (WifiConfiguration net : networks) {
336 if (net.networkId == info.getNetworkId()) {
337 mWifiSsid = net.SSID;
338 break;
339 }
340 }
341 }
342 }
343 }
344
Daniel Sandler764b4da2010-08-24 16:24:35 -0400345 refreshSignalMeters();
346 }
347
348 // figure out what to show: first wifi, then 3G, then nothing
349 void refreshSignalMeters() {
350 if (mSignalMeter == null) return; // no UI yet
351
352 Context ctxt = getContext();
353
354 String text = null;
355 int level = 0;
356
357 if (mWifiConnected) {
358 if (mWifiSsid == null) {
359 text = ctxt.getString(R.string.system_panel_signal_meter_wifi_nossid);
360 } else {
361 text = ctxt.getString(R.string.system_panel_signal_meter_wifi_ssid_format,
362 mWifiSsid);
363 }
364 level = mWifiLevel;
365 } else if (mDataConnected) {
366 text = ctxt.getString(R.string.system_panel_signal_meter_data_connected);
367 level = mDataLevel;
368 } else {
369 text = ctxt.getString(R.string.system_panel_signal_meter_disconnected);
370 level = 0;
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400371 }
372
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400373 mSignalMeter.setImageResource(R.drawable.sysbar_signal);
Daniel Sandler764b4da2010-08-24 16:24:35 -0400374 mSignalMeter.setImageLevel(level);
375 mSignalText.setText(text);
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400376
377 // hack for now
Daniel Sandler764b4da2010-08-24 16:24:35 -0400378 mBar.setSignalMeter(level, mWifiConnected);
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400379 }
380
Daniel Sandler6425ef92010-08-11 16:10:19 -0400381 public void setBar(TabletStatusBarService bar) {
382 mBar = bar;
383 }
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400384
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400385 public void updateBattery(Intent intent) {
386 final int level = intent.getIntExtra("level", 0);
387 final boolean plugged = intent.getIntExtra("plugged", 0) != 0;
388
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400389 mBatteryMeter.setImageResource(R.drawable.sysbar_battery);
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400390 mBatteryMeter.setImageLevel(level);
Daniel Sandler764b4da2010-08-24 16:24:35 -0400391 mBatteryText.setText(getContext()
392 .getString(R.string.system_panel_battery_meter_format, level));
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400393
394 // hack for now
395 mBar.setBatteryMeter(level, plugged);
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400396 }
Daniel Sandler6425ef92010-08-11 16:10:19 -0400397
398 public SystemPanel(Context context, AttributeSet attrs) {
399 this(context, attrs, 0);
400 }
401
402 public SystemPanel(Context context, AttributeSet attrs, int defStyle) {
403 super(context, attrs, defStyle);
404
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400405 // our mighty overlord
406 mWM = IWindowManager.Stub.asInterface(
407 ServiceManager.getService("window"));
408
409
Daniel Sandler6425ef92010-08-11 16:10:19 -0400410 // get notified of phone state changes
411 TelephonyManager telephonyManager =
412 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Daniel Sandler764b4da2010-08-24 16:24:35 -0400413 telephonyManager.listen(mPhoneStateListener,
414 PhoneStateListener.LISTEN_SERVICE_STATE
415 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
416 | PhoneStateListener.LISTEN_CALL_STATE
417 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
418 | PhoneStateListener.LISTEN_DATA_ACTIVITY);
Daniel Sandler6425ef92010-08-11 16:10:19 -0400419
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400420 // wifi status info
421 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
422
Daniel Sandler764b4da2010-08-24 16:24:35 -0400423 // audio status
Daniel Sandler6425ef92010-08-11 16:10:19 -0400424 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
Daniel Sandler764b4da2010-08-24 16:24:35 -0400425
426 // mobile data
427 mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400428
429 // Bluetooth
430 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Daniel Sandler6425ef92010-08-11 16:10:19 -0400431 }
432
433 public void onAttachedToWindow() {
434 TextView settingsButton = (TextView)findViewById(R.id.settings_button);
435 settingsButton.setOnClickListener(new View.OnClickListener() {
436 public void onClick(View v) {
437 getContext().startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)
438 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
439 mBar.animateCollapse();
440 }});
441
442 mBrightnessButton = (ImageButton)findViewById(R.id.brightness);
443 mBrightnessButton.setOnClickListener(new View.OnClickListener() {
444 public void onClick(View v) {
445 rotateBrightness();
446 }
447 });
448
449 mSoundButton = (ImageButton)findViewById(R.id.sound);
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400450 mSoundButton.setAlpha(getSilentMode() ? 0x7F : 0xFF);
Daniel Sandler6425ef92010-08-11 16:10:19 -0400451 mSoundButton.setOnClickListener(new View.OnClickListener() {
452 public void onClick(View v) {
453 setSilentMode(!getSilentMode());
454 mSoundButton.setAlpha(getSilentMode() ? 0x7F : 0xFF);
455 }
456 });
457 mOrientationButton = (ImageButton)findViewById(R.id.orientation);
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400458 mOrientationButton.setImageResource(
459 getAutoRotate()
460 ? R.drawable.ic_sysbar_rotate_on
461 : R.drawable.ic_sysbar_rotate_off);
Daniel Sandler6425ef92010-08-11 16:10:19 -0400462 mOrientationButton.setOnClickListener(new View.OnClickListener() {
463 public void onClick(View v) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400464 setAutoRotate(!getAutoRotate());
465 mOrientationButton.setImageResource(
466 getAutoRotate()
467 ? R.drawable.ic_sysbar_rotate_on
468 : R.drawable.ic_sysbar_rotate_off);
469 Toast.makeText(getContext(),
470 getAutoRotate()
471 ? R.string.toast_rotation_free
472 : R.string.toast_rotation_locked,
473 Toast.LENGTH_SHORT).show();
Daniel Sandler6425ef92010-08-11 16:10:19 -0400474 }
475 });
476
477 mAirplaneButton = (ImageButton)findViewById(R.id.airplane);
478 mAirplaneButton.setAlpha(mAirplaneMode ? 0xFF : 0x7F);
479 mAirplaneButton.setOnClickListener(new View.OnClickListener() {
480 public void onClick(View v) {
481 boolean newMode = !getAirplaneMode();
482 Toast.makeText(getContext(), "Attempting to turn "
483 + (newMode ? "on" : "off") + " airplane mode (flaky).",
484 Toast.LENGTH_SHORT).show();
485 setAirplaneMode(newMode);
486 }
487 });
488
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400489 mGpsButton = (ImageButton)findViewById(R.id.gps);
490 mGpsButton.setOnClickListener(new View.OnClickListener() {
491 public void onClick(View v) {
492 toggleGps();
493 refreshGps();
494 }
495 });
496
497 mBluetoothButton = (ImageButton)findViewById(R.id.bluetooth);
498 mBluetoothButton.setOnClickListener(new View.OnClickListener() {
499 public void onClick(View v) {
500 toggleBluetooth();
501 refreshBluetooth();
502 }
503 });
504
Daniel Sandler764b4da2010-08-24 16:24:35 -0400505 // register for broadcasts
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400506 IntentFilter filter = new IntentFilter();
507 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
508 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Daniel Sandlerd7db7b12010-08-13 16:26:39 -0400509 filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
510 filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
511 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
512 filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
Daniel Sandler764b4da2010-08-24 16:24:35 -0400513 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400514 filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
Daniel Sandler6425ef92010-08-11 16:10:19 -0400515 getContext().registerReceiver(mReceiver, filter);
Daniel Sandler764b4da2010-08-24 16:24:35 -0400516
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400517 mBatteryMeter = (ImageView)findViewById(R.id.battery_meter);
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400518 mBatteryMeter.setImageResource(R.drawable.sysbar_battery);
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400519 mBatteryMeter.setImageLevel(0);
520 mSignalMeter = (ImageView)findViewById(R.id.signal_meter);
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400521 mBatteryMeter.setImageResource(R.drawable.sysbar_signal);
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400522 mBatteryMeter.setImageLevel(0);
523
524 mBatteryText = (TextView)findViewById(R.id.battery_info);
525 mSignalText = (TextView)findViewById(R.id.signal_info);
Daniel Sandler764b4da2010-08-24 16:24:35 -0400526
527 refreshSignalMeters();
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400528 refreshBluetooth();
529 refreshGps();
Daniel Sandler6425ef92010-08-11 16:10:19 -0400530 }
531
532 public void onDetachedFromWindow() {
533 getContext().unregisterReceiver(mReceiver);
534 }
535
536 // ----------------------------------------------------------------------
537
538// private boolean isAutoBrightness() {
539// Context context = getContext();
540// try {
541// IPowerManager power = IPowerManager.Stub.asInterface(
542// ServiceManager.getService("power"));
543// if (power != null) {
544// int brightnessMode = Settings.System.getInt(context.getContentResolver(),
545// Settings.System.SCREEN_BRIGHTNESS_MODE);
546// return brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
547// }
548// } catch (RemoteException e) {
549// } catch (Settings.SettingNotFoundException e) {
550// }
551// return false;
552// }
553
554 private void rotateBrightness() {
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400555 int icon = R.drawable.ic_sysbar_brightness;
556 int bg = R.drawable.sysbar_toggle_bg_on;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400557 Context context = getContext();
558 try {
559 IPowerManager power = IPowerManager.Stub.asInterface(
560 ServiceManager.getService("power"));
561 if (power != null) {
562 ContentResolver cr = context.getContentResolver();
563 int brightness = Settings.System.getInt(cr,
564 Settings.System.SCREEN_BRIGHTNESS);
565 int brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
566 //Only get brightness setting if available
567 if (context.getResources().getBoolean(
568 com.android.internal.R.bool.config_automatic_brightness_available)) {
569 brightnessMode = Settings.System.getInt(cr,
570 Settings.System.SCREEN_BRIGHTNESS_MODE);
571 }
572
573 // Rotate AUTO -> MINIMUM -> DEFAULT -> MAXIMUM
574 // Technically, not a toggle...
575 if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
576 brightness = MINIMUM_BACKLIGHT;
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400577 icon = R.drawable.ic_sysbar_brightness_low;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400578 brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400579 } else if (brightness < DEFAULT_BACKLIGHT) {
580 brightness = DEFAULT_BACKLIGHT;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400581 } else if (brightness < MAXIMUM_BACKLIGHT) {
582 brightness = MAXIMUM_BACKLIGHT;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400583 } else {
584 brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
585 brightness = MINIMUM_BACKLIGHT;
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400586 icon = R.drawable.ic_sysbar_brightness_auto;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400587 }
588
589 if (context.getResources().getBoolean(
590 com.android.internal.R.bool.config_automatic_brightness_available)) {
591 // Set screen brightness mode (automatic or manual)
592 Settings.System.putInt(context.getContentResolver(),
593 Settings.System.SCREEN_BRIGHTNESS_MODE,
594 brightnessMode);
595 } else {
596 // Make sure we set the brightness if automatic mode isn't available
597 brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
598 }
599 if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL) {
600 power.setBacklightBrightness(brightness);
601 Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS, brightness);
602 }
603 }
604 } catch (RemoteException e) {
605 } catch (Settings.SettingNotFoundException e) {
606 }
607
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400608 mBrightnessButton.setImageResource(icon);
609 mBrightnessButton.setBackgroundResource(bg);
Daniel Sandler6425ef92010-08-11 16:10:19 -0400610 }
611
612 PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
613 @Override
614 public void onServiceStateChanged(ServiceState serviceState) {
Daniel Sandler764b4da2010-08-24 16:24:35 -0400615 if (DEBUG_SIGNAL || DEBUG) {
616 Slog.d(TAG, "phone service state changed: " + serviceState.getState());
617 }
618 mServiceState = serviceState;
Daniel Sandler6425ef92010-08-11 16:10:19 -0400619 mAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
620 if (mAirplaneButton != null) {
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400621 mAirplaneButton.setImageResource(mAirplaneMode
622 ? R.drawable.ic_sysbar_airplane_on
623 : R.drawable.ic_sysbar_airplane_off);
624 mAirplaneButton.setBackgroundResource(mAirplaneMode
625 ? R.drawable.sysbar_toggle_bg_on
626 : R.drawable.sysbar_toggle_bg_off);
Daniel Sandler6425ef92010-08-11 16:10:19 -0400627 }
Daniel Sandler764b4da2010-08-24 16:24:35 -0400628 updateDataState();
629 }
630 @Override
631 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
632 if (DEBUG_SIGNAL || DEBUG) {
633 Slog.d(TAG, "onSignalStrengthsChanged: " + signalStrength);
634 }
635 mSignalStrength = signalStrength;
636 updateDataState();
637 }
638 @Override
639 public void onCallStateChanged(int state, String incomingNumber) {
640 mPhoneState = state;
641 // In cdma, if a voice call is made, RSSI should switch to 1x.
642 if (isCdma()) {
643 updateDataState();
644 }
645 }
646
647 @Override
648 public void onDataConnectionStateChanged(int state, int networkType) {
649 if (DEBUG_SIGNAL || DEBUG) {
650 Slog.d(TAG, "onDataConnectionStateChanged: state=" + state
651 + " type=" + networkType);
652 }
653 mDataState = state;
654// updateDataNetType(networkType);
655 updateDataState();
Daniel Sandler6425ef92010-08-11 16:10:19 -0400656 }
657 };
658
659 private boolean getAirplaneMode() {
660 return mAirplaneMode;
661 }
662
663 private void setAirplaneMode(boolean on) {
664 Settings.System.putInt(
665 mContext.getContentResolver(),
666 Settings.System.AIRPLANE_MODE_ON,
667 on ? 1 : 0);
668 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
669 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
670 intent.putExtra("state", on);
671 getContext().sendBroadcast(intent);
672 }
673
674 boolean getSilentMode() {
675 return mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
676 }
677
678 void setSilentMode(boolean on) {
679 if (on) {
680 mAudioManager.setRingerMode((Settings.System.getInt(mContext.getContentResolver(),
681 Settings.System.VIBRATE_IN_SILENT, 1) == 1)
682 ? AudioManager.RINGER_MODE_VIBRATE
683 : AudioManager.RINGER_MODE_SILENT);
684 } else {
685 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
686 }
687 }
688
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400689 void refreshSound() {
690 boolean silent = getSilentMode();
691 mSoundButton.setImageResource(!silent
692 ? R.drawable.ic_sysbar_sound_on
693 : R.drawable.ic_sysbar_sound_off);
694 mSoundButton.setBackgroundResource(!silent
695 ? R.drawable.sysbar_toggle_bg_on
696 : R.drawable.sysbar_toggle_bg_off);
697 }
698
699 void toggleBluetooth() {
700 if (mBluetoothAdapter == null) return;
701 if (mBluetoothAdapter.isEnabled()) {
702 mBluetoothAdapter.disable();
703 } else {
704 mBluetoothAdapter.enable();
705 }
706 }
707
708 void refreshBluetooth() {
709 boolean on = mBluetoothAdapter != null && mBluetoothAdapter.isEnabled();
710 mBluetoothButton.setImageResource(on ? R.drawable.ic_sysbar_bluetooth_on
711 : R.drawable.ic_sysbar_bluetooth_off);
712 mBluetoothButton.setBackgroundResource(on
713 ? R.drawable.sysbar_toggle_bg_on
714 : R.drawable.sysbar_toggle_bg_off);
715 }
716
717 private boolean isGpsEnabled() {
718 ContentResolver res = mContext.getContentResolver();
719 return Settings.Secure.isLocationProviderEnabled(
720 res, LocationManager.GPS_PROVIDER);
721 }
722
723 private void toggleGps() {
724 Settings.Secure.setLocationProviderEnabled(mContext.getContentResolver(),
725 LocationManager.GPS_PROVIDER, !isGpsEnabled());
726 }
727
728 private void refreshGps() {
729 boolean on = isGpsEnabled();
730 mGpsButton.setImageResource(on ? R.drawable.ic_sysbar_gps_on
731 : R.drawable.ic_sysbar_gps_off);
732 mGpsButton.setBackgroundResource(on
733 ? R.drawable.sysbar_toggle_bg_on
734 : R.drawable.sysbar_toggle_bg_off);
735 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400736
737 void setAutoRotate(boolean rot) {
738 try {
739 ContentResolver cr = getContext().getContentResolver();
740 if (rot) {
741 mWM.thawRotation();
742 } else {
743 mWM.freezeRotation();
744 }
745 } catch (android.os.RemoteException exc) {
746 }
747 }
748
749 boolean getAutoRotate() {
750 ContentResolver cr = getContext().getContentResolver();
751 return 1 == Settings.System.getInt(cr,
752 Settings.System.ACCELEROMETER_ROTATION,
753 1);
754 }
755
756 int getDisplayRotation() {
757 try {
758 return mWM.getRotation();
759 } catch (android.os.RemoteException exc) {
760 return 0;
761 }
762 }
Daniel Sandler6425ef92010-08-11 16:10:19 -0400763}