2828import android .content .Intent ;
2929import android .content .IntentFilter ;
3030import android .content .pm .UserInfo ;
31+ import android .database .ContentObserver ;
3132import android .media .AudioManager ;
33+ import android .net .ConnectivityManager ;
3234import android .os .Handler ;
3335import android .os .IBinder ;
3436import android .os .Message ;
@@ -73,7 +75,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
7375 private ArrayList <Action > mItems ;
7476 private AlertDialog mDialog ;
7577
76- private SilentModeAction mSilentModeAction ;
78+ private Action mSilentModeAction ;
7779 private ToggleAction mAirplaneModeOn ;
7880
7981 private MyAdapter mAdapter ;
@@ -82,6 +84,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
8284 private boolean mDeviceProvisioned = false ;
8385 private ToggleAction .State mAirplaneState = ToggleAction .State .Off ;
8486 private boolean mIsWaitingForEcmExit = false ;
87+ private boolean mHasTelephony ;
88+ private boolean mHasVibrator ;
8589
8690 private IWindowManager mIWindowManager ;
8791
@@ -104,6 +108,14 @@ public GlobalActions(Context context, WindowManagerFuncs windowManagerFuncs) {
104108 TelephonyManager telephonyManager =
105109 (TelephonyManager ) context .getSystemService (Context .TELEPHONY_SERVICE );
106110 telephonyManager .listen (mPhoneStateListener , PhoneStateListener .LISTEN_SERVICE_STATE );
111+ ConnectivityManager cm = (ConnectivityManager )
112+ context .getSystemService (Context .CONNECTIVITY_SERVICE );
113+ mHasTelephony = cm .isNetworkSupported (ConnectivityManager .TYPE_MOBILE );
114+ mContext .getContentResolver ().registerContentObserver (
115+ Settings .System .getUriFor (Settings .System .AIRPLANE_MODE_ON ), true ,
116+ mAirplaneModeObserver );
117+ Vibrator vibrator = (Vibrator ) mContext .getSystemService (Context .VIBRATOR_SERVICE );
118+ mHasVibrator = vibrator != null && vibrator .hasVibrator ();
107119 }
108120
109121 /**
@@ -130,13 +142,18 @@ private void handleShow() {
130142 mDialog .show ();
131143 mDialog .getWindow ().getDecorView ().setSystemUiVisibility (View .STATUS_BAR_DISABLE_EXPAND );
132144 }
145+
133146 /**
134147 * Create the global actions dialog.
135148 * @return A new dialog.
136149 */
137150 private AlertDialog createDialog () {
138- mSilentModeAction = new SilentModeAction (mContext , mAudioManager , mHandler );
139-
151+ // Simple toggle style if there's no vibrator, otherwise use a tri-state
152+ if (!mHasVibrator ) {
153+ mSilentModeAction = new SilentModeToggleAction ();
154+ } else {
155+ mSilentModeAction = new SilentModeTriStateAction (mContext , mAudioManager , mHandler );
156+ }
140157 mAirplaneModeOn = new ToggleAction (
141158 R .drawable .ic_lock_airplane_mode ,
142159 R .drawable .ic_lock_airplane_mode_off ,
@@ -145,7 +162,7 @@ private AlertDialog createDialog() {
145162 R .string .global_actions_airplane_mode_off_status ) {
146163
147164 void onToggle (boolean on ) {
148- if (Boolean .parseBoolean (
165+ if (mHasTelephony && Boolean .parseBoolean (
149166 SystemProperties .get (TelephonyProperties .PROPERTY_INECM_MODE ))) {
150167 mIsWaitingForEcmExit = true ;
151168 // Launch ECM exit dialog
@@ -160,6 +177,8 @@ void onToggle(boolean on) {
160177
161178 @ Override
162179 protected void changeStateFromPress (boolean buttonOn ) {
180+ if (!mHasTelephony ) return ;
181+
163182 // In ECM mode airplane state cannot be changed
164183 if (!(Boolean .parseBoolean (
165184 SystemProperties .get (TelephonyProperties .PROPERTY_INECM_MODE )))) {
@@ -176,6 +195,7 @@ public boolean showBeforeProvisioning() {
176195 return false ;
177196 }
178197 };
198+ onAirplaneModeChanged ();
179199
180200 mItems = new ArrayList <Action >();
181201
@@ -247,6 +267,7 @@ public boolean showBeforeProvisioning() {
247267 mItems .add (switchToUser );
248268 }
249269 }
270+
250271 mAdapter = new MyAdapter ();
251272
252273 final AlertDialog .Builder ab = new AlertDialog .Builder (mContext );
@@ -273,8 +294,7 @@ public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
273294 }
274295
275296 private void prepareDialog () {
276- final boolean silentModeOn =
277- mAudioManager .getRingerMode () != AudioManager .RINGER_MODE_NORMAL ;
297+ refreshSilentMode ();
278298 mAirplaneModeOn .updateState (mAirplaneState );
279299 mAdapter .notifyDataSetChanged ();
280300 if (mKeyguardShowing ) {
@@ -288,6 +308,15 @@ private void prepareDialog() {
288308 }
289309 }
290310
311+ private void refreshSilentMode () {
312+ if (!mHasVibrator ) {
313+ final boolean silentModeOn =
314+ mAudioManager .getRingerMode () != AudioManager .RINGER_MODE_NORMAL ;
315+ ((ToggleAction )mSilentModeAction ).updateState (
316+ silentModeOn ? ToggleAction .State .On : ToggleAction .State .Off );
317+ }
318+ }
319+
291320 /** {@inheritDoc} */
292321 public void onDismiss (DialogInterface dialog ) {
293322 if (SHOW_SILENT_TOGGLE ) {
@@ -297,7 +326,7 @@ public void onDismiss(DialogInterface dialog) {
297326
298327 /** {@inheritDoc} */
299328 public void onClick (DialogInterface dialog , int which ) {
300- if (!(mAdapter .getItem (which ) instanceof SilentModeAction )) {
329+ if (!(mAdapter .getItem (which ) instanceof SilentModeTriStateAction )) {
301330 dialog .dismiss ();
302331 }
303332 mAdapter .getItem (which ).onPress ();
@@ -495,12 +524,12 @@ public boolean inTransition() {
495524 */
496525 public ToggleAction (int enabledIconResId ,
497526 int disabledIconResid ,
498- int essage ,
527+ int message ,
499528 int enabledStatusMessageResId ,
500529 int disabledStatusMessageResId ) {
501530 mEnabledIconResId = enabledIconResId ;
502531 mDisabledIconResid = disabledIconResid ;
503- mMessageResId = essage ;
532+ mMessageResId = message ;
504533 mEnabledStatusMessageResId = enabledStatusMessageResId ;
505534 mDisabledStatusMessageResId = disabledStatusMessageResId ;
506535 }
@@ -583,21 +612,44 @@ public void updateState(State state) {
583612 }
584613 }
585614
586- private static class SilentModeAction implements Action , View .OnClickListener {
615+ private class SilentModeToggleAction extends ToggleAction {
616+ public SilentModeToggleAction () {
617+ super (R .drawable .ic_audio_vol_mute ,
618+ R .drawable .ic_audio_vol ,
619+ R .string .global_action_toggle_silent_mode ,
620+ R .string .global_action_silent_mode_on_status ,
621+ R .string .global_action_silent_mode_off_status );
622+ }
623+
624+ void onToggle (boolean on ) {
625+ if (on ) {
626+ mAudioManager .setRingerMode (AudioManager .RINGER_MODE_SILENT );
627+ } else {
628+ mAudioManager .setRingerMode (AudioManager .RINGER_MODE_NORMAL );
629+ }
630+ }
631+
632+ public boolean showDuringKeyguard () {
633+ return true ;
634+ }
635+
636+ public boolean showBeforeProvisioning () {
637+ return false ;
638+ }
639+ }
640+
641+ private static class SilentModeTriStateAction implements Action , View .OnClickListener {
587642
588643 private final int [] ITEM_IDS = { R .id .option1 , R .id .option2 , R .id .option3 };
589644
590645 private final AudioManager mAudioManager ;
591646 private final Handler mHandler ;
592- private final boolean mHasVibrator ;
593647 private final Context mContext ;
594648
595- SilentModeAction (Context context , AudioManager audioManager , Handler handler ) {
649+ SilentModeTriStateAction (Context context , AudioManager audioManager , Handler handler ) {
596650 mAudioManager = audioManager ;
597651 mHandler = handler ;
598652 mContext = context ;
599- Vibrator vibrator = (Vibrator ) mContext .getSystemService (Context .VIBRATOR_SERVICE );
600- mHasVibrator = vibrator != null && vibrator .hasVibrator ();
601653 }
602654
603655 private int ringerModeToIndex (int ringerMode ) {
@@ -621,9 +673,6 @@ public View create(Context context, View convertView, ViewGroup parent,
621673 // Set up click handler
622674 itemView .setTag (i );
623675 itemView .setOnClickListener (this );
624- if (itemView .getId () == R .id .option2 && !mHasVibrator ) {
625- itemView .setVisibility (View .GONE );
626- }
627676 }
628677 return v ;
629678 }
@@ -683,6 +732,7 @@ public void onReceive(Context context, Intent intent) {
683732 PhoneStateListener mPhoneStateListener = new PhoneStateListener () {
684733 @ Override
685734 public void onServiceStateChanged (ServiceState serviceState ) {
735+ if (!mHasTelephony ) return ;
686736 final boolean inAirplaneMode = serviceState .getState () == ServiceState .STATE_POWER_OFF ;
687737 mAirplaneState = inAirplaneMode ? ToggleAction .State .On : ToggleAction .State .Off ;
688738 mAirplaneModeOn .updateState (mAirplaneState );
@@ -699,6 +749,13 @@ public void onReceive(Context context, Intent intent) {
699749 }
700750 };
701751
752+ private ContentObserver mAirplaneModeObserver = new ContentObserver (new Handler ()) {
753+ @ Override
754+ public void onChange (boolean selfChange ) {
755+ onAirplaneModeChanged ();
756+ }
757+ };
758+
702759 private static final int MESSAGE_DISMISS = 0 ;
703760 private static final int MESSAGE_REFRESH = 1 ;
704761 private static final int MESSAGE_SHOW = 2 ;
@@ -713,6 +770,7 @@ public void handleMessage(Message msg) {
713770 }
714771 break ;
715772 case MESSAGE_REFRESH :
773+ refreshSilentMode ();
716774 mAdapter .notifyDataSetChanged ();
717775 break ;
718776 case MESSAGE_SHOW :
@@ -722,6 +780,18 @@ public void handleMessage(Message msg) {
722780 }
723781 };
724782
783+ private void onAirplaneModeChanged () {
784+ // Let the service state callbacks handle the state.
785+ if (mHasTelephony ) return ;
786+
787+ boolean airplaneModeOn = Settings .System .getInt (
788+ mContext .getContentResolver (),
789+ Settings .System .AIRPLANE_MODE_ON ,
790+ 0 ) == 1 ;
791+ mAirplaneState = airplaneModeOn ? ToggleAction .State .On : ToggleAction .State .Off ;
792+ mAirplaneModeOn .updateState (mAirplaneState );
793+ }
794+
725795 /**
726796 * Change the airplane mode system setting
727797 */
@@ -734,6 +804,9 @@ private void changeAirplaneModeSystemSetting(boolean on) {
734804 intent .addFlags (Intent .FLAG_RECEIVER_REPLACE_PENDING );
735805 intent .putExtra ("state" , on );
736806 mContext .sendBroadcast (intent );
807+ if (!mHasTelephony ) {
808+ mAirplaneState = on ? ToggleAction .State .On : ToggleAction .State .Off ;
809+ }
737810 }
738811
739812 private IWindowManager getWindowManager () {
0 commit comments