1 /*
2  * Copyright (C) 2007 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.settings;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.database.ContentObserver;
22 import android.os.Handler;
23 import android.os.Message;
24 import android.os.SystemProperties;
25 import android.os.UserHandle;
26 import android.provider.Settings;
27 import android.support.v14.preference.SwitchPreference;
28 import android.support.v7.preference.Preference;
29 
30 import com.android.internal.logging.MetricsLogger;
31 import com.android.internal.logging.MetricsProto.MetricsEvent;
32 import com.android.internal.telephony.PhoneStateIntentReceiver;
33 import com.android.internal.telephony.TelephonyProperties;
34 import com.android.settingslib.WirelessUtils;
35 
36 public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListener {
37 
38     private final Context mContext;
39 
40     private PhoneStateIntentReceiver mPhoneStateReceiver;
41 
42     private final SwitchPreference mSwitchPref;
43 
44     private static final int EVENT_SERVICE_STATE_CHANGED = 3;
45 
46     private Handler mHandler = new Handler() {
47         @Override
48         public void handleMessage(Message msg) {
49             switch (msg.what) {
50                 case EVENT_SERVICE_STATE_CHANGED:
51                     onAirplaneModeChanged();
52                     break;
53             }
54         }
55     };
56 
57     private ContentObserver mAirplaneModeObserver = new ContentObserver(new Handler()) {
58         @Override
59         public void onChange(boolean selfChange) {
60             onAirplaneModeChanged();
61         }
62     };
63 
AirplaneModeEnabler(Context context, SwitchPreference airplaneModeSwitchPreference)64     public AirplaneModeEnabler(Context context, SwitchPreference airplaneModeSwitchPreference) {
65 
66         mContext = context;
67         mSwitchPref = airplaneModeSwitchPreference;
68 
69         airplaneModeSwitchPreference.setPersistent(false);
70 
71         mPhoneStateReceiver = new PhoneStateIntentReceiver(mContext, mHandler);
72         mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
73     }
74 
resume()75     public void resume() {
76 
77         mSwitchPref.setChecked(WirelessUtils.isAirplaneModeOn(mContext));
78 
79         mPhoneStateReceiver.registerIntent();
80         mSwitchPref.setOnPreferenceChangeListener(this);
81         mContext.getContentResolver().registerContentObserver(
82                 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
83                 mAirplaneModeObserver);
84     }
85 
pause()86     public void pause() {
87         mPhoneStateReceiver.unregisterIntent();
88         mSwitchPref.setOnPreferenceChangeListener(null);
89         mContext.getContentResolver().unregisterContentObserver(mAirplaneModeObserver);
90     }
91 
setAirplaneModeOn(boolean enabling)92     private void setAirplaneModeOn(boolean enabling) {
93         // Change the system setting
94         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
95                                 enabling ? 1 : 0);
96         // Update the UI to reflect system setting
97         mSwitchPref.setChecked(enabling);
98 
99         // Post the intent
100         Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
101         intent.putExtra("state", enabling);
102         mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
103     }
104 
105     /**
106      * Called when we've received confirmation that the airplane mode was set.
107      * TODO: We update the checkbox summary when we get notified
108      * that mobile radio is powered up/down. We should not have dependency
109      * on one radio alone. We need to do the following:
110      * - handle the case of wifi/bluetooth failures
111      * - mobile does not send failure notification, fail on timeout.
112      */
onAirplaneModeChanged()113     private void onAirplaneModeChanged() {
114         mSwitchPref.setChecked(WirelessUtils.isAirplaneModeOn(mContext));
115     }
116 
117     /**
118      * Called when someone clicks on the checkbox preference.
119      */
onPreferenceChange(Preference preference, Object newValue)120     public boolean onPreferenceChange(Preference preference, Object newValue) {
121         if (Boolean.parseBoolean(
122                     SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
123             // In ECM mode, do not update database at this point
124         } else {
125             Boolean value = (Boolean) newValue;
126             MetricsLogger.action(mContext, MetricsEvent.ACTION_AIRPLANE_TOGGLE, value);
127             setAirplaneModeOn(value);
128         }
129         return true;
130     }
131 
setAirplaneModeInECM(boolean isECMExit, boolean isAirplaneModeOn)132     public void setAirplaneModeInECM(boolean isECMExit, boolean isAirplaneModeOn) {
133         if (isECMExit) {
134             // update database based on the current checkbox state
135             setAirplaneModeOn(isAirplaneModeOn);
136         } else {
137             // update summary
138             onAirplaneModeChanged();
139         }
140     }
141 
142 }
143