1149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar/* 2149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Copyright (C) 2016 The Android Open Source Project 3149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * 4149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Licensed under the Apache License, Version 2.0 (the "License"); 5149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * you may not use this file except in compliance with the License. 6149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * You may obtain a copy of the License at 7149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * 8149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * http://www.apache.org/licenses/LICENSE-2.0 9149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * 10149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Unless required by applicable law or agreed to in writing, software 11149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * distributed under the License is distributed on an "AS IS" BASIS, 12149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * See the License for the specific language governing permissions and 14149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * limitations under the License. 15149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */ 16149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 17149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarpackage com.android.internal.telephony; 18149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 19149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.PendingIntent; 20149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.Notification; 21149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.NotificationManager; 22149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.BroadcastReceiver; 23149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.Context; 24149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.Intent; 25149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.IntentFilter; 26149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.os.Handler; 27149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.os.Message; 28149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.os.PersistableBundle; 29149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.provider.Settings; 30149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.telephony.CarrierConfigManager; 31149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.telephony.Rlog; 32149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 337c29cabeb38ae8cb4f5764c2dc0a768de22d2f92fionaxuimport com.android.internal.telephony.util.NotificationChannelController; 3413ff522d752715d856bd4068d39a769cd0d54a24fionaxu 35149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar/** 36149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * This contains Carrier specific logic based on the states/events 37149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * managed in ServiceStateTracker. 38149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * {@hide} 39149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */ 40149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarpublic class CarrierServiceStateTracker extends Handler { 41149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private static final String LOG_TAG = "CSST"; 42149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar protected static final int CARRIER_EVENT_BASE = 100; 43149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar protected static final int CARRIER_EVENT_VOICE_REGISTRATION = CARRIER_EVENT_BASE + 1; 44149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar protected static final int CARRIER_EVENT_VOICE_DEREGISTRATION = CARRIER_EVENT_BASE + 2; 45149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar protected static final int CARRIER_EVENT_DATA_REGISTRATION = CARRIER_EVENT_BASE + 3; 46149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar protected static final int CARRIER_EVENT_DATA_DEREGISTRATION = CARRIER_EVENT_BASE + 4; 47149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private static final int SHOW_NOTIFICATION = 200; 48149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private static final int NOTIFICATION_ID = 1000; 49149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private static final int UNINITIALIZED_DELAY_VALUE = -1; 50149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private int mDelay = UNINITIALIZED_DELAY_VALUE; 51149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private Phone mPhone; 52149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private boolean mIsPhoneRegistered = false; 53149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private ServiceStateTracker mSST; 54149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 55149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar public CarrierServiceStateTracker(Phone phone, ServiceStateTracker sst) { 56149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar this.mPhone = phone; 57149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar this.mSST = sst; 58149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar phone.getContext().registerReceiver(mBroadcastReceiver, new IntentFilter( 59149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)); 60149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 61149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 62149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar @Override 63149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar public void handleMessage(Message msg) { 64149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar switch (msg.what) { 65149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar case CARRIER_EVENT_VOICE_REGISTRATION: 66149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar case CARRIER_EVENT_DATA_REGISTRATION: 67149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar mIsPhoneRegistered = true; 68149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar handleConfigChanges(); 69149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar break; 70149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar case CARRIER_EVENT_VOICE_DEREGISTRATION: 71149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar case CARRIER_EVENT_DATA_DEREGISTRATION: 72149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar if (isGlobalModeOrRadioOffOrAirplaneMode()) { 73149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar break; 74149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 75149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar mIsPhoneRegistered = false; 76149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar handleConfigChanges(); 77149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar break; 78149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar case SHOW_NOTIFICATION: 79149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar sendNotification(); 80149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar break; 81149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 82149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 83149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 84149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar /** 85149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Returns true if the preferred network is set to 'Global' or the radio is off or in 86149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Airplane Mode else returns false. 87149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */ 88149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private boolean isGlobalModeOrRadioOffOrAirplaneMode() { 89149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Context context = mPhone.getContext(); 90149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar int preferredNetworkSetting = -1; 91149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar int airplaneMode = -1; 92149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar int subId = mPhone.getSubId(); 93149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar try { 94149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar preferredNetworkSetting = 95149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar android.provider.Settings.Global.getInt(context.getContentResolver(), 96149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId, 97149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Phone.PREFERRED_NT_MODE); 98149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar airplaneMode = Settings.Global.getInt(context.getContentResolver(), 99149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Settings.Global.AIRPLANE_MODE_ON, 0); 100149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } catch (Exception e) { 101149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Rlog.e(LOG_TAG, "Unable to get PREFERRED_NETWORK_MODE."); 102149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar return true; 103149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 104149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar return ((preferredNetworkSetting == RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) || 105149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar !mSST.isRadioOn() || (airplaneMode != 0)); 106149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 107149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 108149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar /** 109149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Contains logic to decide when to create/cancel notifications. 110149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */ 111149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private void handleConfigChanges() { 112149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 113149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar if (mDelay == UNINITIALIZED_DELAY_VALUE) { 114149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar cancelNotification(); 115149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar return; 116149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 117149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar // send a notification if the device is registerd to a network. 118149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar if (mIsPhoneRegistered) { 119149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar cancelNotification(); 120149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Rlog.i(LOG_TAG, "canceling all notifications. "); 121149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } else { 122149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Message notificationMsg; 123149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar notificationMsg = obtainMessage(SHOW_NOTIFICATION, null); 124149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Rlog.i(LOG_TAG, "starting timer for notifications. "); 125149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar sendMessageDelayed(notificationMsg, mDelay); 126149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 127149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 128149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 129149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 130149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar @Override 131149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar public void onReceive(Context context, Intent intent) { 132149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar CarrierConfigManager carrierConfigManager = (CarrierConfigManager) 133149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar context.getSystemService(Context.CARRIER_CONFIG_SERVICE); 134149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar PersistableBundle b = carrierConfigManager.getConfig(); 135149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar mDelay = b.getInt(CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT); 136149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Rlog.i(LOG_TAG, "reading time to delay notification: " + mDelay); 137149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar handleConfigChanges(); 138149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 139149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar }; 140149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 141149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar /** 142149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Post a notification to the NotificationManager for changing network type. 143149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */ 144149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private void sendNotification() { 145149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Context context = mPhone.getContext(); 146149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 147149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Rlog.i(LOG_TAG, "w/values: " + "," + mIsPhoneRegistered + "," + mDelay 148149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar + "," + isGlobalModeOrRadioOffOrAirplaneMode() + "," + mSST.isRadioOn()); 149149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 150149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar // exit if the network preference is set to Global or if the phone is registered. 151149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar if (isGlobalModeOrRadioOffOrAirplaneMode() || mIsPhoneRegistered) { 152149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar return; 153149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 154149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 155149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar NotificationManager notificationManager = (NotificationManager) 156149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar context.getSystemService(Context.NOTIFICATION_SERVICE); 157149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 158149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 159149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Intent notificationIntent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS); 160149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, notificationIntent, 161149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar PendingIntent.FLAG_ONE_SHOT); 162149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 163149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar CharSequence title = 164149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar context.getText(com.android.internal.R.string.NetworkPreferenceSwitchTitle); 165149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar CharSequence details = 166149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar context.getText(com.android.internal.R.string.NetworkPreferenceSwitchSummary); 167149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 168149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 1697c29cabeb38ae8cb4f5764c2dc0a768de22d2f92fionaxu Notification mNotification = new Notification.Builder(context) 170149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar .setWhen(System.currentTimeMillis()) 171149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar .setAutoCancel(true) 172149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning) 173149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar .setContentTitle(title) 174149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar .setColor(context.getResources().getColor( 175149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar com.android.internal.R.color.system_notification_accent_color)) 176149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar .setStyle(new Notification.BigTextStyle().bigText(details)) 177149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar .setContentText(details) 178149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar .setContentIntent(settingsIntent) 1797c29cabeb38ae8cb4f5764c2dc0a768de22d2f92fionaxu .setChannel(NotificationChannelController.CHANNEL_ID_ALERT) 180149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar .build(); 181149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 182149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar notificationManager.notify(NOTIFICATION_ID, mNotification); 183149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 184149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar 185149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar /** 186149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Cancel notifications if a registration is pending or has been sent. 187149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */ 188149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar private void cancelNotification() { 189149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar Context context = mPhone.getContext(); 190149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar mIsPhoneRegistered = true; 191149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar NotificationManager notificationManager = (NotificationManager) 192149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar context.getSystemService(Context.NOTIFICATION_SERVICE); 193149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar notificationManager.cancel(NOTIFICATION_ID); 194149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar } 195149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar}