diff options
author | Pankaj Kanwar <pkanwar@google.com> | 2016-12-17 17:13:02 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-12-17 17:13:02 +0000 |
commit | c0cb41db168a22ed827e5c64fc0589f08e6e7651 (patch) | |
tree | 6521a29e62e6b0766c28d5e5ed8a28adfbb14a1c | |
parent | d92c67aa965200385acf3182ffb0af25297a366f (diff) | |
parent | 149f0d5d1ce3cebe17479d61454c33f700c3584b (diff) | |
download | android_frameworks_opt_telephony-c0cb41db168a22ed827e5c64fc0589f08e6e7651.tar.gz android_frameworks_opt_telephony-c0cb41db168a22ed827e5c64fc0589f08e6e7651.tar.bz2 android_frameworks_opt_telephony-c0cb41db168a22ed827e5c64fc0589f08e6e7651.zip |
Merge "Notify user when user fails to connect to the network." into nyc-mr2-dev
-rw-r--r-- | src/java/com/android/internal/telephony/CarrierServiceStateTracker.java | 192 | ||||
-rw-r--r-- | src/java/com/android/internal/telephony/ServiceStateTracker.java | 50 |
2 files changed, 242 insertions, 0 deletions
diff --git a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java new file mode 100644 index 000000000..735bfe2ea --- /dev/null +++ b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +import android.app.PendingIntent; +import android.app.Notification; +import android.app.NotificationManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Handler; +import android.os.Message; +import android.os.PersistableBundle; +import android.provider.Settings; +import android.telephony.CarrierConfigManager; +import android.telephony.Rlog; + +/** + * This contains Carrier specific logic based on the states/events + * managed in ServiceStateTracker. + * {@hide} + */ +public class CarrierServiceStateTracker extends Handler { + private static final String LOG_TAG = "CSST"; + protected static final int CARRIER_EVENT_BASE = 100; + protected static final int CARRIER_EVENT_VOICE_REGISTRATION = CARRIER_EVENT_BASE + 1; + protected static final int CARRIER_EVENT_VOICE_DEREGISTRATION = CARRIER_EVENT_BASE + 2; + protected static final int CARRIER_EVENT_DATA_REGISTRATION = CARRIER_EVENT_BASE + 3; + protected static final int CARRIER_EVENT_DATA_DEREGISTRATION = CARRIER_EVENT_BASE + 4; + private static final int SHOW_NOTIFICATION = 200; + private static final int NOTIFICATION_ID = 1000; + private static final int UNINITIALIZED_DELAY_VALUE = -1; + private int mDelay = UNINITIALIZED_DELAY_VALUE; + private Phone mPhone; + private boolean mIsPhoneRegistered = false; + private ServiceStateTracker mSST; + + public CarrierServiceStateTracker(Phone phone, ServiceStateTracker sst) { + this.mPhone = phone; + this.mSST = sst; + phone.getContext().registerReceiver(mBroadcastReceiver, new IntentFilter( + CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case CARRIER_EVENT_VOICE_REGISTRATION: + case CARRIER_EVENT_DATA_REGISTRATION: + mIsPhoneRegistered = true; + handleConfigChanges(); + break; + case CARRIER_EVENT_VOICE_DEREGISTRATION: + case CARRIER_EVENT_DATA_DEREGISTRATION: + if (isGlobalModeOrRadioOffOrAirplaneMode()) { + break; + } + mIsPhoneRegistered = false; + handleConfigChanges(); + break; + case SHOW_NOTIFICATION: + sendNotification(); + break; + } + } + + /** + * Returns true if the preferred network is set to 'Global' or the radio is off or in + * Airplane Mode else returns false. + */ + private boolean isGlobalModeOrRadioOffOrAirplaneMode() { + Context context = mPhone.getContext(); + int preferredNetworkSetting = -1; + int airplaneMode = -1; + int subId = mPhone.getSubId(); + try { + preferredNetworkSetting = + android.provider.Settings.Global.getInt(context.getContentResolver(), + android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId, + Phone.PREFERRED_NT_MODE); + airplaneMode = Settings.Global.getInt(context.getContentResolver(), + Settings.Global.AIRPLANE_MODE_ON, 0); + } catch (Exception e) { + Rlog.e(LOG_TAG, "Unable to get PREFERRED_NETWORK_MODE."); + return true; + } + return ((preferredNetworkSetting == RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) || + !mSST.isRadioOn() || (airplaneMode != 0)); + } + + /** + * Contains logic to decide when to create/cancel notifications. + */ + private void handleConfigChanges() { + + if (mDelay == UNINITIALIZED_DELAY_VALUE) { + cancelNotification(); + return; + } + // send a notification if the device is registerd to a network. + if (mIsPhoneRegistered) { + cancelNotification(); + Rlog.i(LOG_TAG, "canceling all notifications. "); + } else { + Message notificationMsg; + notificationMsg = obtainMessage(SHOW_NOTIFICATION, null); + Rlog.i(LOG_TAG, "starting timer for notifications. "); + sendMessageDelayed(notificationMsg, mDelay); + } + } + + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + CarrierConfigManager carrierConfigManager = (CarrierConfigManager) + context.getSystemService(Context.CARRIER_CONFIG_SERVICE); + PersistableBundle b = carrierConfigManager.getConfig(); + mDelay = b.getInt(CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT); + Rlog.i(LOG_TAG, "reading time to delay notification: " + mDelay); + handleConfigChanges(); + } + }; + + /** + * Post a notification to the NotificationManager for changing network type. + */ + private void sendNotification() { + Context context = mPhone.getContext(); + + Rlog.i(LOG_TAG, "w/values: " + "," + mIsPhoneRegistered + "," + mDelay + + "," + isGlobalModeOrRadioOffOrAirplaneMode() + "," + mSST.isRadioOn()); + + // exit if the network preference is set to Global or if the phone is registered. + if (isGlobalModeOrRadioOffOrAirplaneMode() || mIsPhoneRegistered) { + return; + } + + NotificationManager notificationManager = (NotificationManager) + context.getSystemService(Context.NOTIFICATION_SERVICE); + + + Intent notificationIntent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS); + PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, notificationIntent, + PendingIntent.FLAG_ONE_SHOT); + + CharSequence title = + context.getText(com.android.internal.R.string.NetworkPreferenceSwitchTitle); + CharSequence details = + context.getText(com.android.internal.R.string.NetworkPreferenceSwitchSummary); + + + Notification mNotification = new Notification.Builder(context) + .setWhen(System.currentTimeMillis()) + .setAutoCancel(true) + .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning) + .setContentTitle(title) + .setColor(context.getResources().getColor( + com.android.internal.R.color.system_notification_accent_color)) + .setStyle(new Notification.BigTextStyle().bigText(details)) + .setContentText(details) + .setContentIntent(settingsIntent) + .build(); + + notificationManager.notify(NOTIFICATION_ID, mNotification); + } + + /** + * Cancel notifications if a registration is pending or has been sent. + */ + private void cancelNotification() { + Context context = mPhone.getContext(); + mIsPhoneRegistered = true; + NotificationManager notificationManager = (NotificationManager) + context.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel(NOTIFICATION_ID); + } +}
\ No newline at end of file diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java index fdb5f770a..58eec0c65 100644 --- a/src/java/com/android/internal/telephony/ServiceStateTracker.java +++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java @@ -155,6 +155,7 @@ public class ServiceStateTracker extends Handler { protected RegistrantList mDetachedRegistrants = new RegistrantList(); private RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList(); private RegistrantList mNetworkAttachedRegistrants = new RegistrantList(); + private RegistrantList mNetworkDetachedRegistrants = new RegistrantList(); private RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList(); private RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList(); @@ -423,6 +424,8 @@ public class ServiceStateTracker extends Handler { private boolean mStartedGprsRegCheck; /** Already sent the event-log for no gprs register. */ private boolean mReportedGprsNoReg; + + private CarrierServiceStateTracker mCSST; /** * The Notification object given to the NotificationManager. */ @@ -552,6 +555,17 @@ public class ServiceStateTracker extends Handler { mPhone.notifyOtaspChanged(OTASP_UNINITIALIZED); updatePhoneType(); + + mCSST = new CarrierServiceStateTracker(phone, this); + + registerForNetworkAttached(mCSST, + CarrierServiceStateTracker.CARRIER_EVENT_VOICE_REGISTRATION, null); + registerForNetworkDetached(mCSST, + CarrierServiceStateTracker.CARRIER_EVENT_VOICE_DEREGISTRATION, null); + registerForDataConnectionAttached(mCSST, + CarrierServiceStateTracker.CARRIER_EVENT_DATA_REGISTRATION, null); + registerForDataConnectionDetached(mCSST, + CarrierServiceStateTracker.CARRIER_EVENT_DATA_DEREGISTRATION, null); } @VisibleForTesting @@ -2694,6 +2708,10 @@ public class ServiceStateTracker extends Handler { mNitzUpdatedTime = false; } + if (hasDeregistered) { + mNetworkDetachedRegistrants.notifyRegistrants(); + } + if (hasChanged) { String operatorNumeric; @@ -2848,6 +2866,10 @@ public class ServiceStateTracker extends Handler { mSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE && mNewSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE; + boolean hasDeregistered = + mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE + && mNewSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE; + boolean hasCdmaDataConnectionAttached = mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE && mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE; @@ -2922,6 +2944,10 @@ public class ServiceStateTracker extends Handler { mNetworkAttachedRegistrants.notifyRegistrants(); } + if (hasDeregistered) { + mNetworkDetachedRegistrants.notifyRegistrants(); + } + if (hasChanged) { updateSpnDisplay(); @@ -3161,6 +3187,10 @@ public class ServiceStateTracker extends Handler { mNetworkAttachedRegistrants.notifyRegistrants(); } + if (hasDeregistered) { + mNetworkDetachedRegistrants.notifyRegistrants(); + } + if (hasChanged) { updateSpnDisplay(); @@ -4274,11 +4304,31 @@ public class ServiceStateTracker extends Handler { r.notifyRegistrant(); } } + public void unregisterForNetworkAttached(Handler h) { mNetworkAttachedRegistrants.remove(h); } /** + * Registration point for transition into network detached. + * @param h handler to notify + * @param what what code of message when delivered + * @param obj in Message.obj + */ + public void registerForNetworkDetached(Handler h, int what, Object obj) { + Registrant r = new Registrant(h, what, obj); + + mNetworkDetachedRegistrants.add(r); + if (mSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE) { + r.notifyRegistrant(); + } + } + + public void unregisterForNetworkDetached(Handler h) { + mNetworkDetachedRegistrants.remove(h); + } + + /** * Registration point for transition into packet service restricted zone. * @param h handler to notify * @param what what code of message when delivered |