1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi; 18 19 import android.net.wifi.WifiConfiguration; 20 import android.telephony.SubscriptionManager; 21 import android.util.ArraySet; 22 23 import com.android.server.wifi.util.MissingCounterTimerLockList; 24 25 import java.io.FileDescriptor; 26 import java.io.PrintWriter; 27 import java.util.Set; 28 29 /** 30 * Keep track of the disabled duration for all non-carrier-merged networks. 31 */ 32 public class NonCarrierMergedNetworksStatusTracker { 33 private final Clock mClock; 34 private int mSubscriptionId; 35 private long mDisableStartTimeMs; 36 private long mMinDisableDurationMs; 37 private long mMaxDisableDurationMs; 38 private final MissingCounterTimerLockList<String> mTemporarilyDisabledNonCarrierMergedList; 39 private final Set<String> mTemporarilyDisabledNonCarrierMergedListAtStart; 40 NonCarrierMergedNetworksStatusTracker(Clock clock)41 public NonCarrierMergedNetworksStatusTracker(Clock clock) { 42 mClock = clock; 43 mTemporarilyDisabledNonCarrierMergedList = 44 new MissingCounterTimerLockList<>( 45 WifiConfigManager.SCAN_RESULT_MISSING_COUNT_THRESHOLD, mClock); 46 mTemporarilyDisabledNonCarrierMergedListAtStart = new ArraySet<>(); 47 mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 48 } 49 50 /** 51 * Disable autojoin for all non-carrier-merged networks for the specified duration. 52 * @param subscriptionId the subscription ID of the carrier network. 53 * @param minDisableDurationMs the minimum duration in milliseconds to stay on the carrier 54 * network even if wifi is available. 55 * @param maxDisableDurationMs the maximum duration to disable all non-carrier merged wifi 56 * networks. After this duration passes, all non-carrier merged 57 * networks will get re-enabled for auto connections. 58 */ disableAllNonCarrierMergedNetworks(int subscriptionId, long minDisableDurationMs, long maxDisableDurationMs)59 public void disableAllNonCarrierMergedNetworks(int subscriptionId, long minDisableDurationMs, 60 long maxDisableDurationMs) { 61 mSubscriptionId = subscriptionId; 62 mDisableStartTimeMs = mClock.getElapsedSinceBootMillis(); 63 mMinDisableDurationMs = minDisableDurationMs; 64 mMaxDisableDurationMs = maxDisableDurationMs; 65 } 66 67 /** 68 * Add a SSID or FQDN to the temporary disabled list for the given timer duration. The SSID 69 * or FQDN will be re-enabled when after it is out of range for the specified duration. 70 */ temporarilyDisableNetwork(WifiConfiguration config, long timerDurationMs, long maxDisableDurationMs)71 public void temporarilyDisableNetwork(WifiConfiguration config, long timerDurationMs, 72 long maxDisableDurationMs) { 73 String key = getKeyFromConfig(config); 74 mTemporarilyDisabledNonCarrierMergedList.add(key, timerDurationMs, maxDisableDurationMs); 75 mTemporarilyDisabledNonCarrierMergedListAtStart.add(key); 76 } 77 78 /** 79 * Used to detect whether a disabled network is still in range. 80 * A disabled network that does not show up in the list passed in here for |timerDurationMs| 81 * will be re-enabled. 82 */ update(Set<String> networks)83 public void update(Set<String> networks) { 84 mTemporarilyDisabledNonCarrierMergedList.update(networks); 85 } 86 87 /** 88 * Resets this class and re-enables auto-join for all non-carrier-merged networks. 89 */ clear()90 public void clear() { 91 mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 92 mDisableStartTimeMs = 0; 93 mMinDisableDurationMs = 0; 94 mMaxDisableDurationMs = 0; 95 mTemporarilyDisabledNonCarrierMergedList.clear(); 96 mTemporarilyDisabledNonCarrierMergedListAtStart.clear(); 97 } 98 99 /** 100 * Returns whether the given network should be not allowed for auto-connect. 101 * A network could be disable either because all non-carrier-merged networks are not allowed, 102 * or this specific network is still in the temporarily disabled list. 103 * @param config the network to check whether auto-connect should be disabled on 104 */ isNetworkDisabled(WifiConfiguration config)105 public boolean isNetworkDisabled(WifiConfiguration config) { 106 // All wifi networks are enabled after the max effective duration of the API call passes. 107 if (mClock.getElapsedSinceBootMillis() - mDisableStartTimeMs >= mMaxDisableDurationMs) { 108 clear(); 109 return false; 110 } 111 // always allow a carrier-merged network with matching subscription ID through. 112 if (config.carrierMerged && config.subscriptionId == mSubscriptionId) { 113 return false; 114 } 115 if (shouldDisableAllNonCarrierMergedNetworks()) { 116 return true; 117 } 118 String key = getKeyFromConfig(config); 119 if (mTemporarilyDisabledNonCarrierMergedList.isLocked(key)) { 120 return true; 121 } 122 mTemporarilyDisabledNonCarrierMergedList.remove(key); 123 return false; 124 } 125 getKeyFromConfig(WifiConfiguration config)126 private String getKeyFromConfig(WifiConfiguration config) { 127 return config.isPasspoint() ? config.FQDN : config.SSID; 128 } 129 shouldDisableAllNonCarrierMergedNetworks()130 private boolean shouldDisableAllNonCarrierMergedNetworks() { 131 return mClock.getElapsedSinceBootMillis() - mDisableStartTimeMs < mMinDisableDurationMs; 132 } 133 134 /** 135 * Dump information for debugging. 136 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)137 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 138 pw.println("NonCarrierMergedNetworksStatusTracker - Log Begin ----"); 139 pw.println("mSubscriptionId=" + mSubscriptionId); 140 pw.println("dumpTimeMs=" + mClock.getElapsedSinceBootMillis()); 141 pw.println("mDisableStartTimeMs=" + mDisableStartTimeMs); 142 pw.println("mMinDisableDurationMs=" + mMinDisableDurationMs); 143 pw.println("mMaxDisableDurationMs=" + mMaxDisableDurationMs); 144 pw.println("mTemporarilyDisabledNonCarrierMergedListAtStart="); 145 for (String s : mTemporarilyDisabledNonCarrierMergedListAtStart) { 146 pw.println(s); 147 } 148 pw.println("NonCarrierMergedNetworksStatusTracker - Log End ----"); 149 } 150 } 151