summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/test-current.txt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java8
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java17
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java8
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsService.java62
-rw-r--r--services/net/java/android/net/ip/IpServer.java11
-rw-r--r--telephony/java/android/telephony/SmsManager.java85
-rw-r--r--telephony/java/com/android/internal/telephony/ISms.aidl7
-rw-r--r--telephony/java/com/android/internal/telephony/ISmsImplBase.java6
-rw-r--r--telephony/java/com/android/internal/telephony/SmsCbEtwsInfo.java31
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/BearerData.java30
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SmsMessage.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsMessage.java27
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java42
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsServiceTest.java21
17 files changed, 246 insertions, 125 deletions
diff --git a/api/test-current.txt b/api/test-current.txt
index 075963ef5efd..144e5f5c8f53 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1532,6 +1532,15 @@ package android.telephony {
method public void setVoiceRoamingType(int);
}
+ public final class SmsManager {
+ method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
+ field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
+ field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
+ field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
+ field public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4; // 0x4
+ field public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2; // 0x2
+ }
+
public class TelephonyManager {
method public int getCarrierIdListVersion();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index b7c20aa197ca..b67a9f03822c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -548,7 +548,7 @@ public class MobileSignalController extends SignalController<
}
private boolean isDataDisabled() {
- return !mPhone.getDataEnabled(mSubscriptionInfo.getSubscriptionId());
+ return !mPhone.isDataCapable();
}
@VisibleForTesting
@@ -568,6 +568,7 @@ public class MobileSignalController extends SignalController<
pw.println(" mSignalStrength=" + mSignalStrength + ",");
pw.println(" mDataState=" + mDataState + ",");
pw.println(" mDataNetType=" + mDataNetType + ",");
+ pw.println(" isDataDisabled=" + isDataDisabled() + ",");
}
class MobilePhoneStateListener extends PhoneStateListener {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index c1f88855ac24..02f99a00c1a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -155,7 +155,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
protected void setupNetworkController() {
// For now just pretend to be the data sim, so we can test that too.
mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(true);
+ when(mMockTm.isDataCapable()).thenReturn(true);
setDefaultSubId(mSubId);
setSubscriptions(mSubId);
mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 96fad21ed7a3..2aa933e723c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -119,7 +119,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testNoInternetIcon() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -133,7 +133,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testDataDisabledIcon() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -188,7 +188,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testDataDisabledIcon_UserNotSetup() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -203,7 +203,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testAlwaysShowDataRatIcon() {
setupDefaultSignal();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED,
TelephonyManager.NETWORK_TYPE_GSM);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index ae80d7ef11e5..a71d46cbe886 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2614,9 +2614,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
final boolean valid = ((msg.arg1 & NETWORK_VALIDATION_RESULT_VALID) != 0);
final boolean wasValidated = nai.lastValidated;
final boolean wasDefault = isDefaultNetwork(nai);
- if (nai.everCaptivePortalDetected && !nai.captivePortalLoginNotified
- && valid) {
- nai.captivePortalLoginNotified = true;
+ // Only show a connected notification if the network is pending validation
+ // after the captive portal app was open, and it has now validated.
+ if (nai.captivePortalValidationPending && valid) {
+ // User is now logged in, network validated.
+ nai.captivePortalValidationPending = false;
showNetworkNotification(nai, NotificationType.LOGGED_IN);
}
@@ -2687,9 +2689,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
final int oldScore = nai.getCurrentScore();
nai.lastCaptivePortalDetected = visible;
nai.everCaptivePortalDetected |= visible;
- if (visible) {
- nai.captivePortalLoginNotified = false;
- }
if (nai.lastCaptivePortalDetected &&
Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) {
if (DBG) log("Avoiding captive portal network: " + nai.name());
@@ -3498,6 +3497,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
+ // This runs on a random binder thread, but getNetworkAgentInfoForNetwork is thread-safe,
+ // and captivePortalValidationPending is volatile.
+ final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ if (nai != null) {
+ nai.captivePortalValidationPending = true;
+ }
Binder.withCleanCallingIdentity(() ->
mContext.startActivityAsUser(appIntent, UserHandle.CURRENT));
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 864a793b8f40..5b043799f848 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -155,9 +155,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
// Whether a captive portal was found during the last network validation attempt.
public boolean lastCaptivePortalDetected;
- // Indicates the user was notified of a successful captive portal login since a portal was
- // last detected.
- public boolean captivePortalLoginNotified;
+ // Indicates the captive portal app was opened to show a login UI to the user, but the network
+ // has not validated yet.
+ public volatile boolean captivePortalValidationPending;
// Set to true when partial connectivity was detected.
public boolean partialConnectivity;
@@ -629,7 +629,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
+ "acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} "
+ "everCaptivePortalDetected{" + everCaptivePortalDetected + "} "
+ "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} "
- + "captivePortalLoginNotified{" + captivePortalLoginNotified + "} "
+ + "captivePortalValidationPending{" + captivePortalValidationPending + "} "
+ "partialConnectivity{" + partialConnectivity + "} "
+ "acceptPartialConnectivity{" + networkMisc.acceptPartialConnectivity + "} "
+ "clat{" + clatd + "} "
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 2fc78d6f4760..5505828063ed 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -373,14 +373,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
public void systemReady() {
- mSystemReady = true;
-
- if (!isBandwidthControlEnabled()) {
- Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
- return;
- }
-
synchronized (mStatsLock) {
+ mSystemReady = true;
+
// create data recorders along with historical rotators
mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
@@ -426,7 +421,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// ignored; service lives in system_server
}
- registerPollAlarmLocked();
+ // schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
+ final PendingIntent pollIntent =
+ PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
+
+ final long currentRealtime = SystemClock.elapsedRealtime();
+ mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
+ mSettings.getPollInterval(), pollIntent);
+
registerGlobalAlert();
}
@@ -487,23 +489,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
/**
- * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
- * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
- */
- private void registerPollAlarmLocked() {
- if (mPollIntent != null) {
- mAlarmManager.cancel(mPollIntent);
- }
-
- mPollIntent = PendingIntent.getBroadcast(
- mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
-
- final long currentRealtime = SystemClock.elapsedRealtime();
- mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
- mSettings.getPollInterval(), mPollIntent);
- }
-
- /**
* Register for a global alert that is delivered through
* {@link INetworkManagementEventObserver} once a threshold amount of data
* has been transferred.
@@ -548,8 +533,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
- assertBandwidthControlEnabled();
-
final int callingUid = Binder.getCallingUid();
final int usedFlags = isRateLimitedForPoll(callingUid)
? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
@@ -742,7 +725,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
assertSystemReady();
- assertBandwidthControlEnabled();
// NOTE: if callers want to get non-augmented data, they should go
// through the public API
@@ -753,7 +735,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
assertSystemReady();
- assertBandwidthControlEnabled();
final NetworkStatsCollection uidComplete;
synchronized (mStatsLock) {
@@ -768,7 +749,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
if (Binder.getCallingUid() != uid) {
mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
}
- assertBandwidthControlEnabled();
// TODO: switch to data layer stats once kernel exports
// for now, read network layer stats and flatten across all ifaces
@@ -855,7 +835,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
NetworkState[] networkStates,
String activeIface) {
checkNetworkStackPermission(mContext);
- assertBandwidthControlEnabled();
final long token = Binder.clearCallingIdentity();
try {
@@ -868,7 +847,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public void forceUpdate() {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
- assertBandwidthControlEnabled();
final long token = Binder.clearCallingIdentity();
try {
@@ -879,8 +857,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
private void advisePersistThreshold(long thresholdBytes) {
- assertBandwidthControlEnabled();
-
// clamp threshold into safe range
mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
if (LOGV) {
@@ -1739,24 +1715,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- private void assertBandwidthControlEnabled() {
- if (!isBandwidthControlEnabled()) {
- throw new IllegalStateException("Bandwidth module disabled");
- }
- }
-
- private boolean isBandwidthControlEnabled() {
- final long token = Binder.clearCallingIdentity();
- try {
- return mNetworkManager.isBandwidthControlEnabled();
- } catch (RemoteException e) {
- // ignored; service lives in system_server
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
@Override
public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java
index 66884c60b0bc..6a6a1307723e 100644
--- a/services/net/java/android/net/ip/IpServer.java
+++ b/services/net/java/android/net/ip/IpServer.java
@@ -433,6 +433,9 @@ public class IpServer extends StateMachine {
}
}
ifcg.clearFlag("running");
+
+ // TODO: this may throw if the interface is already gone. Do proper handling and
+ // simplify the DHCP server start/stop.
mNMService.setInterfaceConfig(mIfaceName, ifcg);
if (!configureDhcp(enabled, (Inet4Address) addr, prefixLen)) {
@@ -440,6 +443,14 @@ public class IpServer extends StateMachine {
}
} catch (Exception e) {
mLog.e("Error configuring interface " + e);
+ if (!enabled) {
+ try {
+ // Calling stopDhcp several times is fine
+ stopDhcp();
+ } catch (Exception dhcpError) {
+ mLog.e("Error stopping DHCP", dhcpError);
+ }
+ }
return false;
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 63e3801a9b4f..d4ea29fe1463 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -16,9 +16,11 @@
package android.telephony;
+import android.annotation.IntDef;
import android.annotation.RequiresPermission;
import android.annotation.SuppressAutoDoc;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityThread;
import android.app.PendingIntent;
@@ -43,6 +45,8 @@ import com.android.internal.telephony.ISms;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.SmsRawData;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -2798,4 +2802,85 @@ public final class SmsManager {
config.getBoolean(MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER));
return filtered;
}
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"SMS_CATEGORY_"},
+ value = {
+ SmsManager.SMS_CATEGORY_NOT_SHORT_CODE,
+ SmsManager.SMS_CATEGORY_FREE_SHORT_CODE,
+ SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE,
+ SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE,
+ SmsManager.SMS_CATEGORY_PREMIUM_SHORT_CODE})
+ public @interface SmsShortCodeCategory {}
+
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for regular
+ * phone numbers.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0;
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for free
+ * (no cost) short codes.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1;
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
+ * standard rate (non-premium)
+ * short codes.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2;
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for possible
+ * premium short codes.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
+ * premium short codes.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4;
+
+ /**
+ * Check if the destination address is a possible premium short code.
+ * NOTE: the caller is expected to strip non-digits from the destination number with
+ * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
+ *
+ * @param destAddress the destination address to test for possible short code
+ * @param countryIso the ISO country code
+ *
+ * @return
+ * {@link SmsManager#SMS_CATEGORY_NOT_SHORT_CODE},
+ * {@link SmsManager#SMS_CATEGORY_FREE_SHORT_CODE},
+ * {@link SmsManager#SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE},
+ * {@link SmsManager#SMS_CATEGORY_PREMIUM_SHORT_CODE}, or
+ * {@link SmsManager#SMS_CATEGORY_STANDARD_SHORT_CODE}
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ @TestApi
+ public @SmsShortCodeCategory int checkSmsShortCodeDestination(
+ String destAddress, String countryIso) {
+ try {
+ ISms iccISms = getISmsServiceOrThrow();
+ if (iccISms != null) {
+ return iccISms.checkSmsShortCodeDestination(getSubscriptionId(),
+ ActivityThread.currentPackageName(), destAddress, countryIso);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "checkSmsShortCodeDestination() RemoteException", e);
+ }
+ return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index c3dcc3db7d45..87aff8a57e27 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -551,4 +551,11 @@ interface ISms {
* @param intent PendingIntent to be sent when an SMS is received containing the token.
*/
String createAppSpecificSmsToken(int subId, String callingPkg, in PendingIntent intent);
+
+ /**
+ * Check if the destination is a possible premium short code.
+ *
+ * @param destAddress the destination address to test for possible short code
+ */
+ int checkSmsShortCodeDestination(int subId, String callingApk, String destAddress, String countryIso);
}
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index 1cdf44d897b2..194f46195c55 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -188,4 +188,10 @@ public class ISmsImplBase extends ISms.Stub {
public String createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public int checkSmsShortCodeDestination(
+ int subid, String callingApk, String destAddress, String countryIso) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/SmsCbEtwsInfo.java b/telephony/java/com/android/internal/telephony/SmsCbEtwsInfo.java
index 14e02de276fd..15fbc404756f 100644
--- a/telephony/java/com/android/internal/telephony/SmsCbEtwsInfo.java
+++ b/telephony/java/com/android/internal/telephony/SmsCbEtwsInfo.java
@@ -18,10 +18,11 @@ package android.telephony;
import android.os.Parcel;
import android.os.Parcelable;
-import android.text.format.Time;
import com.android.internal.telephony.uicc.IccUtils;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
import java.util.Arrays;
/**
@@ -165,19 +166,21 @@ public class SmsCbEtwsInfo implements Parcelable {
int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08)));
timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset;
-
- Time time = new Time(Time.TIMEZONE_UTC);
-
- // We only need to support years above 2000.
- time.year = year + 2000;
- time.month = month - 1;
- time.monthDay = day;
- time.hour = hour;
- time.minute = minute;
- time.second = second;
-
- // Timezone offset is in quarter hours.
- return time.toMillis(true) - timezoneOffset * 15 * 60 * 1000;
+ // timezoneOffset is in quarter hours.
+ int timeZoneOffsetSeconds = timezoneOffset * 15 * 60;
+
+ LocalDateTime localDateTime = LocalDateTime.of(
+ // We only need to support years above 2000.
+ year + 2000,
+ month /* 1-12 */,
+ day,
+ hour,
+ minute,
+ second);
+
+ long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds;
+ // Convert to milliseconds, ignore overflow.
+ return epochSeconds * 1000;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/cdma/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/BearerData.java
index 694cc69c2b3f..9e6f19f9243d 100644
--- a/telephony/java/com/android/internal/telephony/cdma/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/BearerData.java
@@ -20,7 +20,6 @@ import android.content.res.Resources;
import android.telephony.SmsCbCmasInfo;
import android.telephony.cdma.CdmaSmsCbProgramData;
import android.telephony.cdma.CdmaSmsCbProgramResults;
-import android.text.format.Time;
import android.telephony.Rlog;
import com.android.internal.telephony.GsmAlphabet;
@@ -32,8 +31,10 @@ import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.util.BitwiseInputStream;
import com.android.internal.util.BitwiseOutputStream;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.util.ArrayList;
-import java.util.TimeZone;
/**
* An object to encode and decode CDMA SMS bearer data.
@@ -228,10 +229,23 @@ public final class BearerData {
/**
* 6-byte-field, see 3GPP2 C.S0015-B, v2, 4.5.4
*/
- public static class TimeStamp extends Time {
+ public static class TimeStamp {
+
+ public int second;
+ public int minute;
+ public int hour;
+ public int monthDay;
+
+ /** Month [0-11] */
+ public int month;
+
+ /** Full year. For example, 1970. */
+ public int year;
+
+ private ZoneId mZoneId;
public TimeStamp() {
- super(TimeZone.getDefault().getID()); // 3GPP2 timestamps use the local timezone
+ mZoneId = ZoneId.systemDefault(); // 3GPP2 timestamps use the local timezone
}
public static TimeStamp fromByteArray(byte[] data) {
@@ -258,6 +272,14 @@ public final class BearerData {
return ts;
}
+ public long toMillis() {
+ LocalDateTime localDateTime =
+ LocalDateTime.of(year, month + 1, monthDay, hour, minute, second);
+ Instant instant = localDateTime.toInstant(mZoneId.getRules().getOffset(localDateTime));
+ return instant.toEpochMilli();
+ }
+
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index da4e3f87730f..e2a8913b91e6 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -718,7 +718,7 @@ public class SmsMessage extends SmsMessageBase {
}
if (mBearerData.msgCenterTimeStamp != null) {
- mScTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true);
+ mScTimeMillis = mBearerData.msgCenterTimeStamp.toMillis();
}
if (VDBG) Rlog.d(LOG_TAG, "SMS SC timestamp: " + mScTimeMillis);
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index a6156ff20912..5667387bdc1b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -17,7 +17,6 @@
package com.android.internal.telephony.gsm;
import android.telephony.PhoneNumberUtils;
-import android.text.format.Time;
import android.telephony.Rlog;
import android.content.res.Resources;
import android.text.TextUtils;
@@ -33,6 +32,8 @@ import com.android.internal.telephony.Sms7BitEncodingTranslator;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
import static com.android.internal.telephony.SmsConstants.MessageClass;
import static com.android.internal.telephony.SmsConstants.ENCODING_UNKNOWN;
@@ -722,19 +723,21 @@ public class SmsMessage extends SmsMessageBase {
int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08)));
timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset;
-
- Time time = new Time(Time.TIMEZONE_UTC);
+ // timezoneOffset is in quarter hours.
+ int timeZoneOffsetSeconds = timezoneOffset * 15 * 60;
// It's 2006. Should I really support years < 2000?
- time.year = year >= 90 ? year + 1900 : year + 2000;
- time.month = month - 1;
- time.monthDay = day;
- time.hour = hour;
- time.minute = minute;
- time.second = second;
-
- // Timezone offset is in quarter hours.
- return time.toMillis(true) - (timezoneOffset * 15 * 60 * 1000);
+ int fullYear = year >= 90 ? year + 1900 : year + 2000;
+ LocalDateTime localDateTime = LocalDateTime.of(
+ fullYear,
+ month /* 1-12 */,
+ day,
+ hour,
+ minute,
+ second);
+ long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds;
+ // Convert to milliseconds.
+ return epochSeconds * 1000;
}
/**
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 7317d625a202..9ac331c884b6 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -18,6 +18,7 @@ package com.android.server;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.NETID_UNSET;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
@@ -84,13 +85,13 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -145,6 +146,7 @@ import android.net.NetworkInfo.DetailedState;
import android.net.NetworkMisc;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
+import android.net.NetworkStack;
import android.net.NetworkStackClient;
import android.net.NetworkState;
import android.net.NetworkUtils;
@@ -158,6 +160,7 @@ import android.net.shared.NetworkMonitorUtils;
import android.net.shared.PrivateDnsConfig;
import android.net.util.MultinetworkPolicyTracker;
import android.os.Binder;
+import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
@@ -195,6 +198,7 @@ import com.android.server.connectivity.DefaultNetworkMetrics;
import com.android.server.connectivity.IpConnectivityMetrics;
import com.android.server.connectivity.MockableSystemProperties;
import com.android.server.connectivity.Nat464Xlat;
+import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
import com.android.server.connectivity.ProxyTracker;
import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
@@ -289,6 +293,7 @@ public class ConnectivityServiceTest {
@Mock NetworkStackClient mNetworkStack;
@Mock PackageManager mPackageManager;
@Mock UserManager mUserManager;
+ @Mock NotificationManager mNotificationManager;
private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
ArgumentCaptor.forClass(ResolverParamsParcel.class);
@@ -358,7 +363,7 @@ public class ConnectivityServiceTest {
@Override
public Object getSystemService(String name) {
if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
- if (Context.NOTIFICATION_SERVICE.equals(name)) return mock(NotificationManager.class);
+ if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager;
if (Context.NETWORK_STACK_SERVICE.equals(name)) return mNetworkStack;
if (Context.USER_SERVICE.equals(name)) return mUserManager;
return super.getSystemService(name);
@@ -378,7 +383,17 @@ public class ConnectivityServiceTest {
public PackageManager getPackageManager() {
return mPackageManager;
}
- }
+
+ @Override
+ public void enforceCallingOrSelfPermission(String permission, String message) {
+ // The mainline permission can only be held if signed with the network stack certificate
+ // Skip testing for this permission.
+ if (NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK.equals(permission)) return;
+ // All other permissions should be held by the test or unnecessary: check as normal to
+ // make sure the code does not rely on unexpected permissions.
+ super.enforceCallingOrSelfPermission(permission, message);
+ }
+ }
public void waitForIdle(int timeoutMsAsInt) {
long timeoutMs = timeoutMsAsInt;
@@ -2863,6 +2878,9 @@ public class ConnectivityServiceTest {
// Expect NET_CAPABILITY_VALIDATED onAvailable callback.
validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+ // Expect no notification to be shown when captive portal disappears by itself
+ verify(mNotificationManager, never()).notifyAsUser(
+ anyString(), eq(NotificationType.LOGGED_IN.eventId), any(), any());
// Break network connectivity.
// Expect NET_CAPABILITY_VALIDATED onLost callback.
@@ -2892,6 +2910,8 @@ public class ConnectivityServiceTest {
// Check that calling startCaptivePortalApp does nothing.
final int fastTimeoutMs = 100;
mCm.startCaptivePortalApp(wifiNetwork);
+ waitForIdle();
+ verify(mWiFiNetworkAgent.mNetworkMonitor, never()).launchCaptivePortalApp();
mServiceContext.expectNoStartActivityIntent(fastTimeoutMs);
// Turn into a captive portal.
@@ -2902,14 +2922,26 @@ public class ConnectivityServiceTest {
// Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
mCm.startCaptivePortalApp(wifiNetwork);
- verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1))
- .launchCaptivePortalApp();
+ waitForIdle();
+ verify(mWiFiNetworkAgent.mNetworkMonitor).launchCaptivePortalApp();
+
+ // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal)
+ final Bundle testBundle = new Bundle();
+ final String testKey = "testkey";
+ final String testValue = "testvalue";
+ testBundle.putString(testKey, testValue);
+ mCm.startCaptivePortalApp(wifiNetwork, testBundle);
+ final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS);
+ assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction());
+ assertEquals(testValue, signInIntent.getStringExtra(testKey));
// Report that the captive portal is dismissed, and check that callbacks are fired
mWiFiNetworkAgent.setNetworkValid();
mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+ verify(mNotificationManager, times(1)).notifyAsUser(anyString(),
+ eq(NotificationType.LOGGED_IN.eventId), any(), eq(UserHandle.ALL));
mCm.unregisterNetworkCallback(validatedCallback);
mCm.unregisterNetworkCallback(captivePortalCallback);
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 1682dd17c4a3..adaef40b51e3 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -239,7 +239,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -283,7 +282,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -357,7 +355,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -398,7 +395,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
@@ -433,7 +429,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
forcePollAndWaitForIdle();
@@ -473,7 +468,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -531,7 +525,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
@@ -558,7 +551,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
forcePollAndWaitForIdle();
@@ -588,7 +580,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -646,7 +637,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -690,7 +680,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -740,7 +729,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -797,7 +785,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildWifiState(true /* isMetered */)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -837,7 +824,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
new NetworkState[] {buildMobile3gState(IMSI_1, true /* isRoaming */)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
@@ -875,7 +861,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
@@ -916,7 +901,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
@@ -1057,7 +1041,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
private void expectSystemReady() throws Exception {
expectNetworkStatsSummary(buildEmptyStats());
- expectBandwidthControlCheck();
}
private String getActiveIface(NetworkState... states) throws Exception {
@@ -1125,10 +1108,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
when(mSettings.getUidTagPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
}
- private void expectBandwidthControlCheck() throws Exception {
- when(mNetManager.isBandwidthControlEnabled()).thenReturn(true);
- }
-
private void assertStatsFilesExist(boolean exist) {
final File basePath = new File(mStatsDir, "netstats");
if (exist) {