Merge "Hide data limit notfication if data not active nor default" am: b6fbb9784f am: 38b31cdf29 am: 233ee2a71b

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2541633

Change-Id: Id4b9cb21837e962de535e1797b079d6ba86a5959
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2023-05-10 00:30:07 +00:00
committed by Automerger Merge Worker
2 changed files with 121 additions and 1 deletions

View File

@@ -222,6 +222,7 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.DateUtils;
@@ -803,6 +804,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
return buckets;
}
/** Require IPC call. Don't call when holding a lock. */
int getDefaultDataSubId() {
return SubscriptionManager.getDefaultDataSubscriptionId();
}
/** Require IPC call. Don't call when holding a lock. */
int getActivateDataSubId() {
return SubscriptionManager.getActiveDataSubscriptionId();
}
}
@VisibleForTesting
@@ -830,7 +841,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mSuppressDefaultPolicy = suppressDefaultPolicy;
mDeps = Objects.requireNonNull(deps, "missing Dependencies");
mActiveDataSubIdListener = new ActiveDataSubIdListener();
mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
mAppOps = context.getSystemService(AppOpsManager.class);
@@ -1090,6 +1101,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
});
// Listen for active data sub Id change, upon which data notifications is shown/hidden.
mContext.getSystemService(TelephonyManager.class).registerTelephonyCallback(executor,
mActiveDataSubIdListener);
// tell systemReady() that the service has been initialized
initCompleteSignal.countDown();
} finally {
@@ -1260,6 +1275,38 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
};
/**
* Listener that watches for active data sub Id change, upon which data notifications are
* shown/hidden.
*/
private final ActiveDataSubIdListener mActiveDataSubIdListener;
private class ActiveDataSubIdListener extends TelephonyCallback implements
TelephonyCallback.ActiveDataSubscriptionIdListener {
/**
* In most cases active data sub is the same as the default data sub, but if user enabled
* auto data switch {@link TelephonyManager#MOBILE_DATA_POLICY_AUTO_DATA_SWITCH},
* active data sub could be the non-default data sub.
*
* If the listener is initialized before the phone process is up, the IPC call to the
* static method of SubscriptionManager lead to INVALID_SUBSCRIPTION_ID to be returned,
* indicating the phone process is unable to determine a valid data sub Id at this point, in
* which case no data notifications should be shown anyway. Later on when an active data
* sub is known, notifications will be re-evaluated by this callback.
*/
private int mDefaultDataSubId = mDeps.getDefaultDataSubId();
private int mActiveDataSubId = mDeps.getActivateDataSubId();
// Only listen to active data sub change is sufficient because default data sub change
// leads to active data sub change as well.
@Override
public void onActiveDataSubscriptionIdChanged(int subId) {
mActiveDataSubId = subId;
mDefaultDataSubId = mDeps.getDefaultDataSubId();
synchronized (mNetworkPoliciesSecondLock) {
updateNotificationsNL();
}
}
}
/**
* Listener that watches for {@link NetworkStatsManager} updates, which
* NetworkPolicyManagerService uses to check against {@link NetworkPolicy#warningBytes}.
@@ -1449,6 +1496,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// ignore policies that aren't relevant to user
if (subId == INVALID_SUBSCRIPTION_ID) continue;
// ignore if the data sub is neither default nor active for data at the moment.
if (subId != mActiveDataSubIdListener.mDefaultDataSubId
&& subId != mActiveDataSubIdListener.mActiveDataSubId) continue;
if (!policy.hasCycle()) continue;
final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager

View File

@@ -157,6 +157,7 @@ import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.MediumTest;
import android.text.TextUtils;
@@ -247,6 +248,7 @@ public class NetworkPolicyManagerServiceTest {
private static final String TEST_WIFI_NETWORK_KEY = "TestWifiNetworkKey";
private static final String TEST_IMSI = "310210";
private static final int TEST_SUB_ID = 42;
private static final int TEST_SUB_ID2 = 24;
private static final Network TEST_NETWORK = mock(Network.class, CALLS_REAL_METHODS);
private static NetworkTemplate sTemplateWifi = new NetworkTemplate.Builder(MATCH_WIFI)
@@ -288,6 +290,8 @@ public class NetworkPolicyManagerServiceTest {
private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor =
ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
private TelephonyCallback.ActiveDataSubscriptionIdListener mActiveDataSubIdListener;
private ActivityManagerInternal mActivityManagerInternal;
private PackageManagerInternal mPackageManagerInternal;
@@ -363,6 +367,8 @@ public class NetworkPolicyManagerServiceTest {
private class TestDependencies extends NetworkPolicyManagerService.Dependencies {
private final SparseArray<NetworkStats.Bucket> mMockedStats = new SparseArray<>();
private int mMockDefaultDataSubId;
private int mMockedActiveDataSubId;
TestDependencies(Context context) {
super(context);
@@ -400,6 +406,21 @@ public class NetworkPolicyManagerServiceTest {
final NetworkStats.Bucket bucket = mMockedStats.get(uid);
setMockedTotalBytes(uid, bucket.getRxBytes() + rxBytes, bucket.getTxBytes() + txBytes);
}
void setDefaultAndActiveDataSubId(int defaultDataSubId, int activeDataSubId) {
mMockDefaultDataSubId = defaultDataSubId;
mMockedActiveDataSubId = activeDataSubId;
}
@Override
int getDefaultDataSubId() {
return mMockDefaultDataSubId;
}
@Override
int getActivateDataSubId() {
return mMockedActiveDataSubId;
}
}
// TODO: Use TestLooperManager instead.
@@ -577,6 +598,14 @@ public class NetworkPolicyManagerServiceTest {
NetworkPolicy defaultPolicy = mService.buildDefaultCarrierPolicy(0, "");
mDefaultWarningBytes = defaultPolicy.warningBytes;
mDefaultLimitBytes = defaultPolicy.limitBytes;
// Catch TelephonyCallback during systemReady().
ArgumentCaptor<TelephonyCallback> telephonyCallbackArgumentCaptor =
ArgumentCaptor.forClass(TelephonyCallback.class);
verify(mTelephonyManager).registerTelephonyCallback(any(),
telephonyCallbackArgumentCaptor.capture());
mActiveDataSubIdListener = (TelephonyCallback.ActiveDataSubscriptionIdListener)
telephonyCallbackArgumentCaptor.getValue();
}
@After
@@ -1357,6 +1386,7 @@ public class NetworkPolicyManagerServiceTest {
reset(mTelephonyManager, mNetworkManager, mNotifManager);
TelephonyManager tmSub = expectMobileDefaults();
clearInvocations(mNotifManager);
mService.updateNetworks();
@@ -1372,6 +1402,7 @@ public class NetworkPolicyManagerServiceTest {
reset(mTelephonyManager, mNetworkManager, mNotifManager);
TelephonyManager tmSub = expectMobileDefaults();
clearInvocations(mNotifManager);
mService.updateNetworks();
@@ -1389,6 +1420,7 @@ public class NetworkPolicyManagerServiceTest {
reset(mTelephonyManager, mNetworkManager, mNotifManager);
TelephonyManager tmSub = expectMobileDefaults();
expectDefaultCarrierConfig();
clearInvocations(mNotifManager);
mService.updateNetworks();
@@ -1405,6 +1437,7 @@ public class NetworkPolicyManagerServiceTest {
reset(mTelephonyManager, mNetworkManager, mNotifManager);
TelephonyManager tmSub = expectMobileDefaults();
clearInvocations(mNotifManager);
mService.updateNetworks();
@@ -1418,6 +1451,7 @@ public class NetworkPolicyManagerServiceTest {
{
reset(mTelephonyManager, mNetworkManager, mNotifManager);
TelephonyManager tmSub = expectMobileDefaults();
clearInvocations(mNotifManager);
mService.snoozeLimit(sTemplateCarrierMetered);
mService.updateNetworks();
@@ -1428,6 +1462,31 @@ public class NetworkPolicyManagerServiceTest {
verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT_SNOOZED),
isA(Notification.class), eq(UserHandle.ALL));
}
// The sub is no longer used for data(e.g. user uses another sub), hide the notifications.
{
reset(mTelephonyManager, mNetworkManager, mNotifManager);
notifyDefaultAndActiveDataSubIdChange(TEST_SUB_ID2, TEST_SUB_ID2);
verify(mNotifManager, atLeastOnce()).cancel(any(), eq(TYPE_LIMIT_SNOOZED));
}
// The sub is not active for data(e.g. due to auto data switch), but still default for data,
// show notification.
{
reset(mTelephonyManager, mNetworkManager, mNotifManager);
notifyDefaultAndActiveDataSubIdChange(TEST_SUB_ID, TEST_SUB_ID2);
verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT_SNOOZED),
isA(Notification.class), eq(UserHandle.ALL));
}
// The sub is active for data, but not the default(e.g. due to auto data switch),
// show notification.
{
reset(mTelephonyManager, mNetworkManager, mNotifManager);
notifyDefaultAndActiveDataSubIdChange(TEST_SUB_ID2, TEST_SUB_ID);
verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT_SNOOZED),
isA(Notification.class), eq(UserHandle.ALL));
}
}
@Test
@@ -2508,6 +2567,7 @@ public class NetworkPolicyManagerServiceTest {
String subscriberId) {
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
createSubscriptionInfoList(subscriptionId));
notifyDefaultAndActiveDataSubIdChange(subscriptionId, subscriptionId);
TelephonyManager subTelephonyManager;
subTelephonyManager = mock(TelephonyManager.class);
@@ -2518,6 +2578,16 @@ public class NetworkPolicyManagerServiceTest {
return subTelephonyManager;
}
/**
* Telephony Manager callback notifies data sub Id changes.
* @param defaultDataSubId The mock default data sub Id.
* @param activeDataSubId The mock active data sub Id.
*/
private void notifyDefaultAndActiveDataSubIdChange(int defaultDataSubId, int activeDataSubId) {
mDeps.setDefaultAndActiveDataSubId(defaultDataSubId, activeDataSubId);
mActiveDataSubIdListener.onActiveDataSubscriptionIdChanged(activeDataSubId);
}
/**
* Creates mock {@link SubscriptionInfo} from subscription id.
*/