aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfionaxu <fionaxu@google.com>2017-05-23 15:04:08 -0700
committerfionaxu <fionaxu@google.com>2017-08-07 23:13:01 -0700
commitd97cb9753d2b17ae21c522d9a438b0e38c529121 (patch)
tree1a58ad14f49a4101a3711e33c41e780ea608321d
parentf97040889a1f970346a92c6e272ab4a58823287c (diff)
downloadtelephony-d97cb9753d2b17ae21c522d9a438b0e38c529121.tar.gz
Notify carrier app of other default networks
When we need to disable data its common for the carrier to send the user text messages explaining why with a URL. The Carrier App will url-clicks in this case and reroute them to a private network. However, it's possible for the user to get other sms's with links and if there is another network to load them on we should not hijack them. This CL adds a new carrier action for carrier apps to register/unregister notifications of other networks from ConnectivityService instead of notifying only when carrier apps has disabled cell data. in that way framework has decoupled the logic of network status registration from cell data status. Bug: 62487488 Test: Manual Change-Id: I0a7b87ad07a0cf2fdb14f939e8f2865eedf7b008
-rw-r--r--src/java/com/android/internal/telephony/CarrierActionAgent.java64
-rw-r--r--src/java/com/android/internal/telephony/CarrierSignalAgent.java72
-rw-r--r--src/java/com/android/internal/telephony/GsmCdmaPhone.java4
-rw-r--r--src/java/com/android/internal/telephony/Phone.java13
-rw-r--r--tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java19
5 files changed, 141 insertions, 31 deletions
diff --git a/src/java/com/android/internal/telephony/CarrierActionAgent.java b/src/java/com/android/internal/telephony/CarrierActionAgent.java
index 0a7980bd30..6b9a70af41 100644
--- a/src/java/com/android/internal/telephony/CarrierActionAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierActionAgent.java
@@ -54,25 +54,29 @@ public class CarrierActionAgent extends Handler {
private static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE);
/** A list of carrier actions */
- public static final int CARRIER_ACTION_SET_METERED_APNS_ENABLED = 0;
- public static final int CARRIER_ACTION_SET_RADIO_ENABLED = 1;
- public static final int CARRIER_ACTION_RESET = 2;
- public static final int EVENT_APM_SETTINGS_CHANGED = 3;
- public static final int EVENT_MOBILE_DATA_SETTINGS_CHANGED = 4;
- public static final int EVENT_DATA_ROAMING_OFF = 5;
- public static final int EVENT_SIM_STATE_CHANGED = 6;
+ public static final int CARRIER_ACTION_SET_METERED_APNS_ENABLED = 0;
+ public static final int CARRIER_ACTION_SET_RADIO_ENABLED = 1;
+ public static final int CARRIER_ACTION_RESET = 2;
+ public static final int CARRIER_ACTION_REPORT_DEFAULT_NETWORK_STATUS = 3;
+ public static final int EVENT_APM_SETTINGS_CHANGED = 4;
+ public static final int EVENT_MOBILE_DATA_SETTINGS_CHANGED = 5;
+ public static final int EVENT_DATA_ROAMING_OFF = 6;
+ public static final int EVENT_SIM_STATE_CHANGED = 7;
/** Member variables */
private final Phone mPhone;
/** registrant list per carrier action */
private RegistrantList mMeteredApnEnableRegistrants = new RegistrantList();
private RegistrantList mRadioEnableRegistrants = new RegistrantList();
+ private RegistrantList mDefaultNetworkReportRegistrants = new RegistrantList();
/** local log for carrier actions */
private LocalLog mMeteredApnEnabledLog = new LocalLog(10);
private LocalLog mRadioEnabledLog = new LocalLog(10);
- /** carrier actions, true by default */
+ private LocalLog mReportDefaultNetworkStatusLog = new LocalLog(10);
+ /** carrier actions */
private Boolean mCarrierActionOnMeteredApnEnabled = true;
private Boolean mCarrierActionOnRadioEnabled = true;
+ private Boolean mCarrierActionReportDefaultNetworkStatus = false;
/** content observer for APM change */
private final SettingsObserver mSettingsObserver;
@@ -102,6 +106,9 @@ public class CarrierActionAgent extends Handler {
@Override
public void handleMessage(Message msg) {
+ // skip notification if the input carrier action is same as the current one.
+ Boolean enabled = getCarrierActionEnabled(msg.what);
+ if (enabled != null && enabled == (boolean) msg.obj) return;
switch (msg.what) {
case CARRIER_ACTION_SET_METERED_APNS_ENABLED:
mCarrierActionOnMeteredApnEnabled = (boolean) msg.obj;
@@ -118,6 +125,15 @@ public class CarrierActionAgent extends Handler {
mRadioEnableRegistrants.notifyRegistrants(
new AsyncResult(null, mCarrierActionOnRadioEnabled, null));
break;
+ case CARRIER_ACTION_REPORT_DEFAULT_NETWORK_STATUS:
+ mCarrierActionReportDefaultNetworkStatus = (boolean) msg.obj;
+ log("CARRIER_ACTION_REPORT_AT_DEFAULT_NETWORK_STATUS: "
+ + mCarrierActionReportDefaultNetworkStatus);
+ mReportDefaultNetworkStatusLog.log("REGISTER_DEFAULT_NETWORK_STATUS: "
+ + mCarrierActionReportDefaultNetworkStatus);
+ mDefaultNetworkReportRegistrants.notifyRegistrants(
+ new AsyncResult(null, mCarrierActionReportDefaultNetworkStatus, null));
+ break;
case CARRIER_ACTION_RESET:
log("CARRIER_ACTION_RESET");
carrierActionReset();
@@ -171,17 +187,6 @@ public class CarrierActionAgent extends Handler {
}
/**
- * Return current carrier action values
- */
- public Object getCarrierActionValue(int action) {
- Object val = getCarrierAction(action);
- if (val == null) {
- throw new IllegalArgumentException("invalid carrier action: " + action);
- }
- return val;
- }
-
- /**
* Action set from carrier app to enable/disable radio
*/
public void carrierActionSetRadioEnabled(boolean enabled) {
@@ -195,7 +200,15 @@ public class CarrierActionAgent extends Handler {
sendMessage(obtainMessage(CARRIER_ACTION_SET_METERED_APNS_ENABLED, enabled));
}
+ /**
+ * Action set from carrier app to start/stop reporting default network status.
+ */
+ public void carrierActionReportDefaultNetworkStatus(boolean report) {
+ sendMessage(obtainMessage(CARRIER_ACTION_REPORT_DEFAULT_NETWORK_STATUS, report));
+ }
+
private void carrierActionReset() {
+ carrierActionReportDefaultNetworkStatus(false);
carrierActionSetMeteredApnsEnabled(true);
carrierActionSetRadioEnabled(true);
// notify configured carrier apps for reset
@@ -209,18 +222,22 @@ public class CarrierActionAgent extends Handler {
return mMeteredApnEnableRegistrants;
case CARRIER_ACTION_SET_RADIO_ENABLED:
return mRadioEnableRegistrants;
+ case CARRIER_ACTION_REPORT_DEFAULT_NETWORK_STATUS:
+ return mDefaultNetworkReportRegistrants;
default:
loge("Unsupported action: " + action);
return null;
}
}
- private Object getCarrierAction(int action) {
+ private Boolean getCarrierActionEnabled(int action) {
switch (action) {
case CARRIER_ACTION_SET_METERED_APNS_ENABLED:
return mCarrierActionOnMeteredApnEnabled;
case CARRIER_ACTION_SET_RADIO_ENABLED:
return mCarrierActionOnRadioEnabled;
+ case CARRIER_ACTION_REPORT_DEFAULT_NETWORK_STATUS:
+ return mCarrierActionReportDefaultNetworkStatus;
default:
loge("Unsupported action: " + action);
return null;
@@ -235,7 +252,7 @@ public class CarrierActionAgent extends Handler {
*/
public void registerForCarrierAction(int action, Handler h, int what, Object obj,
boolean notifyNow) {
- Object carrierAction = getCarrierAction(action);
+ Boolean carrierAction = getCarrierActionEnabled(action);
if (carrierAction == null) {
throw new IllegalArgumentException("invalid carrier action: " + action);
}
@@ -287,5 +304,10 @@ public class CarrierActionAgent extends Handler {
ipw.increaseIndent();
mRadioEnabledLog.dump(fd, ipw, args);
ipw.decreaseIndent();
+
+ pw.println(" mCarrierActionReportDefaultNetworkStatus Log:");
+ ipw.increaseIndent();
+ mReportDefaultNetworkStatusLog.dump(fd, ipw, args);
+ ipw.decreaseIndent();
}
}
diff --git a/src/java/com/android/internal/telephony/CarrierSignalAgent.java b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
index c6958cf6ea..f2dd2aaf70 100644
--- a/src/java/com/android/internal/telephony/CarrierSignalAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
@@ -22,6 +22,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
@@ -49,7 +54,7 @@ import static android.telephony.CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIG
* repeated polling and send the intent to the interested receivers.
* Each CarrierSignalAgent is associated with a phone object.
*/
-public class CarrierSignalAgent {
+public class CarrierSignalAgent extends Handler {
private static final String LOG_TAG = CarrierSignalAgent.class.getSimpleName();
private static final boolean DBG = true;
@@ -63,6 +68,7 @@ public class CarrierSignalAgent {
/** Member variables */
private final Phone mPhone;
+ private boolean mDefaultNetworkAvail;
/**
* This is a map of intent action -> set of component name of statically registered
@@ -84,6 +90,8 @@ public class CarrierSignalAgent {
*/
private Map<String, Set<ComponentName>> mCachedNoWakeSignalConfigs = new HashMap<>();
+ private static final int EVENT_REGISTER_DEFAULT_NETWORK_AVAIL = 0;
+
/**
* This is a list of supported signals from CarrierSignalAgent
*/
@@ -91,7 +99,8 @@ public class CarrierSignalAgent {
TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE,
TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED,
TelephonyIntents.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED,
- TelephonyIntents.ACTION_CARRIER_SIGNAL_RESET));
+ TelephonyIntents.ACTION_CARRIER_SIGNAL_RESET,
+ TelephonyIntents.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE));
private final LocalLog mErrorLocalLog = new LocalLog(20);
@@ -105,6 +114,8 @@ public class CarrierSignalAgent {
}
};
+ private ConnectivityManager.NetworkCallback mNetworkCallback;
+
/** Constructor */
public CarrierSignalAgent(Phone phone) {
mPhone = phone;
@@ -112,6 +123,61 @@ public class CarrierSignalAgent {
// reload configurations on CARRIER_CONFIG_CHANGED
mPhone.getContext().registerReceiver(mReceiver,
new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+ mPhone.getCarrierActionAgent().registerForCarrierAction(
+ CarrierActionAgent.CARRIER_ACTION_REPORT_DEFAULT_NETWORK_STATUS, this,
+ EVENT_REGISTER_DEFAULT_NETWORK_AVAIL, null, false);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_REGISTER_DEFAULT_NETWORK_AVAIL:
+ AsyncResult ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ Rlog.e(LOG_TAG, "Register default network exception: " + ar.exception);
+ return;
+ }
+ final ConnectivityManager connectivityMgr = ConnectivityManager
+ .from(mPhone.getContext());
+ if ((boolean) ar.result) {
+ mNetworkCallback = new ConnectivityManager.NetworkCallback() {
+ @Override
+ public void onAvailable(Network network) {
+ // an optimization to avoid signaling on every default network switch.
+ if (!mDefaultNetworkAvail) {
+ if (DBG) log("Default network available: " + network);
+ Intent intent = new Intent(TelephonyIntents
+ .ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE);
+ intent.putExtra(
+ TelephonyIntents.EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY, true);
+ notifyCarrierSignalReceivers(intent);
+ mDefaultNetworkAvail = true;
+ }
+ }
+ @Override
+ public void onLost(Network network) {
+ if (DBG) log("Default network lost: " + network);
+ Intent intent = new Intent(TelephonyIntents
+ .ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE);
+ intent.putExtra(
+ TelephonyIntents.EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY, false);
+ notifyCarrierSignalReceivers(intent);
+ mDefaultNetworkAvail = false;
+ }
+ };
+ connectivityMgr.registerDefaultNetworkCallback(mNetworkCallback, mPhone);
+ log("Register default network");
+
+ } else if (mNetworkCallback != null) {
+ connectivityMgr.unregisterNetworkCallback(mNetworkCallback);
+ mNetworkCallback = null;
+ mDefaultNetworkAvail = false;
+ log("unregister default network");
+ }
+ break;
+ default:
+ break;
+ }
}
/**
@@ -316,6 +382,8 @@ public class CarrierSignalAgent {
}
ipw.decreaseIndent();
+ pw.println("mDefaultNetworkAvail: " + mDefaultNetworkAvail);
+
pw.println("error log:");
ipw.increaseIndent();
mErrorLocalLog.dump(fd, pw, args);
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index d479f8ee42..63a23bd8a0 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -205,6 +205,10 @@ public class GsmCdmaPhone extends Phone {
mPrecisePhoneType = precisePhoneType;
initOnce(ci);
initRatSpecific(precisePhoneType);
+ // CarrierSignalAgent uses CarrierActionAgent in construction so it needs to be created
+ // after CarrierActionAgent.
+ mCarrierActionAgent = mTelephonyComponentFactory.makeCarrierActionAgent(this);
+ mCarrierSignalAgent = mTelephonyComponentFactory.makeCarrierSignalAgent(this);
mSST = mTelephonyComponentFactory.makeServiceStateTracker(this, this.mCi);
// DcTracker uses SST so needs to be created after it is instantiated
mDcTracker = mTelephonyComponentFactory.makeDcTracker(this);
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 26d20c1ca1..11c8e610a8 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -250,9 +250,9 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
private boolean mDnsCheckDisabled;
public DcTracker mDcTracker;
/* Used for dispatching signals to configured carrier apps */
- private CarrierSignalAgent mCarrierSignalAgent;
+ protected CarrierSignalAgent mCarrierSignalAgent;
/* Used for dispatching carrier action from carrier apps */
- private CarrierActionAgent mCarrierActionAgent;
+ protected CarrierActionAgent mCarrierActionAgent;
private boolean mDoesRilSendMultipleCallRing;
private int mCallRingContinueToken;
private int mCallRingDelay;
@@ -534,8 +534,6 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
mSmsUsageMonitor = mTelephonyComponentFactory.makeSmsUsageMonitor(context);
mUiccController = UiccController.getInstance();
mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
- mCarrierSignalAgent = mTelephonyComponentFactory.makeCarrierSignalAgent(this);
- mCarrierActionAgent = mTelephonyComponentFactory.makeCarrierActionAgent(this);
mSimActivationTracker = mTelephonyComponentFactory.makeSimActivationTracker(this);
if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) {
mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
@@ -2810,6 +2808,13 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
}
/**
+ * Action set from carrier app to start/stop reporting default network condition.
+ */
+ public void carrierActionReportDefaultNetworkStatus(boolean report) {
+ mCarrierActionAgent.carrierActionReportDefaultNetworkStatus(report);
+ }
+
+ /**
* Notify registrants of a new ringing Connection.
* Subclasses of Phone probably want to replace this with a
* version scoped to their packages
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
index ca21914323..2294decbf0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify;
import android.content.Intent;
import android.database.ContentObserver;
import android.net.Uri;
+import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -106,13 +107,21 @@ public class CarrierActionAgentTest extends TelephonyTest {
mContext.sendBroadcast(intent);
waitForMs(200);
- // carrier actions triggered from sim loading
+ // no carrier actions triggered from sim loading since there are same as the current one
ArgumentCaptor<Message> message = ArgumentCaptor.forClass(Message.class);
- verify(mDataActionHandler).sendMessageAtTime(message.capture(), anyLong());
- assertEquals(DATA_CARRIER_ACTION_EVENT, message.getValue().what);
+ verify(mDataActionHandler, times(0)).sendMessageAtTime(message.capture(), anyLong());
+ verify(mRadioActionHandler, times(0)).sendMessageAtTime(message.capture(), anyLong());
- verify(mRadioActionHandler).sendMessageAtTime(message.capture(), anyLong());
+ // disable metered apns and radio
+ mCarrierActionAgentUT.carrierActionSetRadioEnabled(false);
+ mCarrierActionAgentUT.carrierActionSetMeteredApnsEnabled(false);
+ waitForMs(200);
+ verify(mDataActionHandler, times(1)).sendMessageAtTime(message.capture(), anyLong());
+ assertEquals(DATA_CARRIER_ACTION_EVENT, message.getValue().what);
+ assertEquals(false, ((AsyncResult) message.getValue().obj).result);
+ verify(mRadioActionHandler, times(1)).sendMessageAtTime(message.capture(), anyLong());
assertEquals(RADIO_CARRIER_ACTION_EVENT, message.getValue().what);
+ assertEquals(false, ((AsyncResult) message.getValue().obj).result);
// simulate APM change from off -> on
Settings.Global.putInt(mFakeContentResolver, Settings.Global.AIRPLANE_MODE_ON, 1);
@@ -123,9 +132,11 @@ public class CarrierActionAgentTest extends TelephonyTest {
// carrier actions triggered from APM
verify(mDataActionHandler, times(2)).sendMessageAtTime(message.capture(), anyLong());
assertEquals(DATA_CARRIER_ACTION_EVENT, message.getValue().what);
+ assertEquals(true, ((AsyncResult) message.getValue().obj).result);
verify(mRadioActionHandler, times(2)).sendMessageAtTime(message.capture(), anyLong());
assertEquals(RADIO_CARRIER_ACTION_EVENT, message.getValue().what);
+ assertEquals(true, ((AsyncResult) message.getValue().obj).result);
}
@After