blob: 6028c188d9fd8132fbaa325d3dbb2db17c2453c8 [file] [log] [blame]
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001/*
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
17package com.android.settings;
18
Fan Zhang31b21002019-01-16 13:49:47 -080019import android.app.settings.SettingsEnums;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080020import android.content.Context;
21import android.content.Intent;
Jason Chiu1766b3c2020-04-09 14:29:58 +080022import android.os.Looper;
Christopher Tate6a5929b2012-09-10 15:39:05 -070023import android.os.UserHandle;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080024import android.provider.Settings;
Bonian Chen5980b802019-11-12 17:36:00 +080025import android.telephony.PhoneStateListener;
Bonian Chen5980b802019-11-12 17:36:00 +080026import android.telephony.SubscriptionInfo;
Bonian Chen5980b802019-11-12 17:36:00 +080027import android.telephony.TelephonyManager;
28import android.util.Log;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080029
Bonian Chen717e0762020-01-02 12:01:10 +080030import androidx.annotation.VisibleForTesting;
31
Bonian Chen5980b802019-11-12 17:36:00 +080032import com.android.settings.network.GlobalSettingsChangeListener;
33import com.android.settings.network.ProxySubscriptionManager;
34import com.android.settings.overlay.FeatureFactory;
Jason Monkfc1b00c2015-01-28 10:35:53 -050035import com.android.settingslib.WirelessUtils;
Leif Hendrik Wilden28dee1f2018-01-11 10:15:36 -080036import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
Chouting Zhang71cc49e2009-08-28 14:36:35 -050037
Bonian Chen5980b802019-11-12 17:36:00 +080038import java.util.List;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080039
Bonian Chen5980b802019-11-12 17:36:00 +080040/**
41 * Monitor and update configuration of airplane mode settings
42 */
43public class AirplaneModeEnabler extends GlobalSettingsChangeListener {
44
45 private static final String LOG_TAG = "AirplaneModeEnabler";
46 private static final boolean DEBUG = false;
Fan Zhangaa71afe2016-09-22 10:43:12 -070047
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080048 private final Context mContext;
Fan Zhangaa71afe2016-09-22 10:43:12 -070049 private final MetricsFeatureProvider mMetricsFeatureProvider;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080050
CY Chengfee48072018-03-26 18:38:59 +080051 private OnAirplaneModeChangedListener mOnAirplaneModeChangedListener;
52
53 public interface OnAirplaneModeChangedListener {
54 /**
55 * Called when airplane mode status is changed.
56 *
57 * @param isAirplaneModeOn the airplane mode is on
58 */
59 void onAirplaneModeChanged(boolean isAirplaneModeOn);
60 }
61
Bonian Chen5980b802019-11-12 17:36:00 +080062 private TelephonyManager mTelephonyManager;
Bonian Chen717e0762020-01-02 12:01:10 +080063 @VisibleForTesting
64 PhoneStateListener mPhoneStateListener;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080065
Bonian Chena72a0382019-12-31 16:59:37 +080066 public AirplaneModeEnabler(Context context, OnAirplaneModeChangedListener listener) {
Bonian Chen5980b802019-11-12 17:36:00 +080067 super(context, Settings.Global.AIRPLANE_MODE_ON);
Fan Zhangaa71afe2016-09-22 10:43:12 -070068
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080069 mContext = context;
Bonian Chen5980b802019-11-12 17:36:00 +080070 mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
CY Chengfee48072018-03-26 18:38:59 +080071 mOnAirplaneModeChangedListener = listener;
Fan Zhangaa71afe2016-09-22 10:43:12 -070072
Bonian Chen5980b802019-11-12 17:36:00 +080073 mTelephonyManager = context.getSystemService(TelephonyManager.class);
Bonian Chena72a0382019-12-31 16:59:37 +080074
Jason Chiu1766b3c2020-04-09 14:29:58 +080075 mPhoneStateListener = new PhoneStateListener(Looper.getMainLooper()) {
Bonian Chena72a0382019-12-31 16:59:37 +080076 @Override
77 public void onRadioPowerStateChanged(int state) {
78 if (DEBUG) {
79 Log.d(LOG_TAG, "RadioPower: " + state);
80 }
81 onAirplaneModeChanged();
82 }
83 };
Bonian Chen5980b802019-11-12 17:36:00 +080084 }
85
86 /**
87 * Implementation of GlobalSettingsChangeListener.onChanged
88 */
Jason Chiu1766b3c2020-04-09 14:29:58 +080089 @Override
Bonian Chen5980b802019-11-12 17:36:00 +080090 public void onChanged(String field) {
91 if (DEBUG) {
92 Log.d(LOG_TAG, "Airplane mode configuration update");
93 }
94 onAirplaneModeChanged();
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080095 }
96
Jason Chiu1766b3c2020-04-09 14:29:58 +080097 /**
98 * Start listening to the phone state change
99 */
100 public void start() {
Bonian Chena72a0382019-12-31 16:59:37 +0800101 mTelephonyManager.listen(mPhoneStateListener,
102 PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800103 }
Fan Zhangaa71afe2016-09-22 10:43:12 -0700104
Jason Chiu1766b3c2020-04-09 14:29:58 +0800105 /**
106 * Stop listening to the phone state change
107 */
108 public void stop() {
Bonian Chena72a0382019-12-31 16:59:37 +0800109 mTelephonyManager.listen(mPhoneStateListener,
110 PhoneStateListener.LISTEN_NONE);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800111 }
Amith Yamasanib98c00e2011-01-26 09:56:44 -0800112
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800113 private void setAirplaneModeOn(boolean enabling) {
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800114 // Change the system setting
Fan Zhangaa71afe2016-09-22 10:43:12 -0700115 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
116 enabling ? 1 : 0);
CY Chengfee48072018-03-26 18:38:59 +0800117
118 // Notify listener the system setting is changed.
119 if (mOnAirplaneModeChangedListener != null) {
120 mOnAirplaneModeChangedListener.onAirplaneModeChanged(enabling);
121 }
Fan Zhangaa71afe2016-09-22 10:43:12 -0700122
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800123 // Post the intent
Bonian Chen5980b802019-11-12 17:36:00 +0800124 final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800125 intent.putExtra("state", enabling);
Christopher Tate6a5929b2012-09-10 15:39:05 -0700126 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800127 }
128
129 /**
130 * Called when we've received confirmation that the airplane mode was set.
Irfan Sheriffecea11f2010-08-02 19:11:16 -0700131 * TODO: We update the checkbox summary when we get notified
132 * that mobile radio is powered up/down. We should not have dependency
133 * on one radio alone. We need to do the following:
134 * - handle the case of wifi/bluetooth failures
135 * - mobile does not send failure notification, fail on timeout.
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800136 */
137 private void onAirplaneModeChanged() {
CY Chengfee48072018-03-26 18:38:59 +0800138 if (mOnAirplaneModeChangedListener != null) {
139 mOnAirplaneModeChangedListener.onAirplaneModeChanged(isAirplaneModeOn());
140 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800141 }
Fan Zhangaa71afe2016-09-22 10:43:12 -0700142
Bonian Chen5980b802019-11-12 17:36:00 +0800143 /**
144 * Check the status of ECM mode
145 *
146 * @return any subscription within device is under ECM mode
147 */
148 public boolean isInEcmMode() {
149 if (mTelephonyManager.getEmergencyCallbackMode()) {
150 return true;
151 }
152 final List<SubscriptionInfo> subInfoList =
Bonian Chen717e0762020-01-02 12:01:10 +0800153 ProxySubscriptionManager.getInstance(mContext).getActiveSubscriptionsInfo();
Bonian Chen5980b802019-11-12 17:36:00 +0800154 if (subInfoList == null) {
155 return false;
156 }
157 for (SubscriptionInfo subInfo : subInfoList) {
158 final TelephonyManager telephonyManager =
159 mTelephonyManager.createForSubscriptionId(subInfo.getSubscriptionId());
160 if (telephonyManager != null) {
161 if (telephonyManager.getEmergencyCallbackMode()) {
162 return true;
163 }
164 }
165 }
166 return false;
167 }
168
CY Chengfee48072018-03-26 18:38:59 +0800169 public void setAirplaneMode(boolean isAirplaneModeOn) {
Bonian Chen5980b802019-11-12 17:36:00 +0800170 if (isInEcmMode()) {
Chouting Zhang71cc49e2009-08-28 14:36:35 -0500171 // In ECM mode, do not update database at this point
Bonian Chen5980b802019-11-12 17:36:00 +0800172 Log.d(LOG_TAG, "ECM airplane mode=" + isAirplaneModeOn);
Chouting Zhang71cc49e2009-08-28 14:36:35 -0500173 } else {
Fan Zhang31b21002019-01-16 13:49:47 -0800174 mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AIRPLANE_TOGGLE,
CY Chengfee48072018-03-26 18:38:59 +0800175 isAirplaneModeOn);
176 setAirplaneModeOn(isAirplaneModeOn);
Chouting Zhang71cc49e2009-08-28 14:36:35 -0500177 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800178 }
179
Chouting Zhang71cc49e2009-08-28 14:36:35 -0500180 public void setAirplaneModeInECM(boolean isECMExit, boolean isAirplaneModeOn) {
Bonian Chen5980b802019-11-12 17:36:00 +0800181 Log.d(LOG_TAG, "Exist ECM=" + isECMExit + ", with airplane mode=" + isAirplaneModeOn);
Chouting Zhang71cc49e2009-08-28 14:36:35 -0500182 if (isECMExit) {
183 // update database based on the current checkbox state
184 setAirplaneModeOn(isAirplaneModeOn);
185 } else {
Irfan Sheriffecea11f2010-08-02 19:11:16 -0700186 // update summary
Chouting Zhang71cc49e2009-08-28 14:36:35 -0500187 onAirplaneModeChanged();
188 }
189 }
190
CY Chengfee48072018-03-26 18:38:59 +0800191 public boolean isAirplaneModeOn() {
192 return WirelessUtils.isAirplaneModeOn(mContext);
193 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800194}