blob: 0919385dccc456c3bfc199e034f763a15afcd1bb [file] [log] [blame]
/*
* Copyright (C) 2022 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.phone;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.UserManager;
import android.telephony.RadioAccessFamily;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.RILConstants;
import java.util.List;
import java.util.concurrent.Executor;
/**
* A {@link BroadcastReceiver} that ensures that user restrictions are correctly applied to
* telephony.
* This includes handling broadcasts from user restriction state changes, as well as ensuring that
* SIM-specific settings are correctly applied when new subscriptions become active.
*
* Callers are expected to call {@code init()} and keep an instance of this class alive.
*/
public class Telephony2gUpdater extends BroadcastReceiver {
private static final String TAG = "TelephonyUserManagerReceiver";
// We can't interact with the HAL on the main thread of the phone process (where
// receivers are run by default), so we execute our logic from a separate thread.
private final Executor mExecutor;
private final Context mContext;
private final long mBaseAllowedNetworks;
public Telephony2gUpdater(Executor executor, Context context) {
this(executor, context,
RadioAccessFamily.getRafFromNetworkType(RILConstants.PREFERRED_NETWORK_MODE));
}
public Telephony2gUpdater(Executor executor, Context context,
long baseAllowedNetworks) {
mExecutor = executor;
mContext = context;
mBaseAllowedNetworks = baseAllowedNetworks;
}
/**
* Register the given instance as a {@link BroadcastReceiver} and a {@link
* SubscriptionManager.OnSubscriptionsChangedListener}.
*/
public void init() {
mContext.getSystemService(SubscriptionManager.class).addOnSubscriptionsChangedListener(
mExecutor, new SubscriptionListener());
IntentFilter filter = new IntentFilter();
filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
mContext.registerReceiver(this, filter);
}
@Override
public void onReceive(Context context, Intent intent) {
if (context == null || intent == null) return;
Log.i(TAG, "Received callback for action " + intent.getAction());
final PendingResult result = goAsync();
mExecutor.execute(() -> {
Log.i(TAG, "Running handler for action " + intent.getAction());
handleUserRestrictionsChanged(context);
result.finish();
});
}
/**
* Update all active subscriptions with allowed network types depending on the current state
* of the {@link UserManager.DISALLOW_2G}.
*/
@VisibleForTesting
public void handleUserRestrictionsChanged(Context context) {
UserManager um = context.getSystemService(UserManager.class);
TelephonyManager tm = context.getSystemService(TelephonyManager.class);
SubscriptionManager sm = context.getSystemService(SubscriptionManager.class);
final long twoGBitmask = TelephonyManager.NETWORK_CLASS_BITMASK_2G;
boolean shouldDisable2g = um.hasUserRestriction(UserManager.DISALLOW_CELLULAR_2G);
// This is expected when subscription info cannot be determined. We'll get another
// callback in the future from our SubscriptionListener once we have valid subscriptions.
List<SubscriptionInfo> subscriptionInfoList = sm.getAvailableSubscriptionInfoList();
if (subscriptionInfoList == null) {
return;
}
long allowedNetworkTypes = mBaseAllowedNetworks;
// 2G device admin controls are global
for (SubscriptionInfo info : subscriptionInfoList) {
TelephonyManager telephonyManager = tm.createForSubscriptionId(
info.getSubscriptionId());
if (shouldDisable2g) {
allowedNetworkTypes &= ~twoGBitmask;
} else {
allowedNetworkTypes |= twoGBitmask;
}
telephonyManager.setAllowedNetworkTypesForReason(
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS,
allowedNetworkTypes);
}
}
private class SubscriptionListener extends SubscriptionManager.OnSubscriptionsChangedListener {
@Override
public void onSubscriptionsChanged() {
Log.i(TAG, "Running handler for subscription change.");
handleUserRestrictionsChanged(mContext);
}
}
}