aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPankaj Kanwar <pkanwar@google.com>2016-12-17 17:13:02 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2016-12-17 17:13:02 +0000
commitc0cb41db168a22ed827e5c64fc0589f08e6e7651 (patch)
tree6521a29e62e6b0766c28d5e5ed8a28adfbb14a1c
parentd92c67aa965200385acf3182ffb0af25297a366f (diff)
parent149f0d5d1ce3cebe17479d61454c33f700c3584b (diff)
downloadandroid_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.java192
-rw-r--r--src/java/com/android/internal/telephony/ServiceStateTracker.java50
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