Merge "Refactor the EntitlementManager"
This commit is contained in:
@@ -45,13 +45,13 @@ import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.StateMachine;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.BitSet;
|
||||
|
||||
/**
|
||||
* Re-check tethering provisioning for enabled downstream tether types.
|
||||
@@ -74,11 +74,11 @@ public class EntitlementManager {
|
||||
private final ComponentName mSilentProvisioningService;
|
||||
private static final int MS_PER_HOUR = 60 * 60 * 1000;
|
||||
|
||||
// The ArraySet contains enabled downstream types, ex:
|
||||
// The BitSet is the bit map of each enabled downstream types, ex:
|
||||
// {@link TetheringManager.TETHERING_WIFI}
|
||||
// {@link TetheringManager.TETHERING_USB}
|
||||
// {@link TetheringManager.TETHERING_BLUETOOTH}
|
||||
private final ArraySet<Integer> mCurrentTethers;
|
||||
private final BitSet mCurrentDownstreams;
|
||||
private final Context mContext;
|
||||
private final int mPermissionChangeMessageCode;
|
||||
private final SharedLog mLog;
|
||||
@@ -87,9 +87,9 @@ public class EntitlementManager {
|
||||
private final StateMachine mTetherMasterSM;
|
||||
// Key: TetheringManager.TETHERING_*(downstream).
|
||||
// Value: TetheringManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result).
|
||||
private final SparseIntArray mCellularPermitted;
|
||||
private final SparseIntArray mCurrentEntitlementResults;
|
||||
private PendingIntent mProvisioningRecheckAlarm;
|
||||
private boolean mCellularUpstreamPermitted = true;
|
||||
private boolean mLastCellularUpstreamPermitted = true;
|
||||
private boolean mUsingCellularAsUpstream = false;
|
||||
private boolean mNeedReRunProvisioningUi = false;
|
||||
private OnUiEntitlementFailedListener mListener;
|
||||
@@ -97,11 +97,10 @@ public class EntitlementManager {
|
||||
|
||||
public EntitlementManager(Context ctx, StateMachine tetherMasterSM, SharedLog log,
|
||||
int permissionChangeMessageCode) {
|
||||
|
||||
mContext = ctx;
|
||||
mLog = log.forSubComponent(TAG);
|
||||
mCurrentTethers = new ArraySet<Integer>();
|
||||
mCellularPermitted = new SparseIntArray();
|
||||
mCurrentDownstreams = new BitSet();
|
||||
mCurrentEntitlementResults = new SparseIntArray();
|
||||
mEntitlementCacheValue = new SparseIntArray();
|
||||
mTetherMasterSM = tetherMasterSM;
|
||||
mPermissionChangeMessageCode = permissionChangeMessageCode;
|
||||
@@ -144,13 +143,19 @@ public class EntitlementManager {
|
||||
* Check if cellular upstream is permitted.
|
||||
*/
|
||||
public boolean isCellularUpstreamPermitted() {
|
||||
// If provisioning is required and EntitlementManager don't know any downstream,
|
||||
// cellular upstream should not be allowed.
|
||||
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
|
||||
if (mCurrentTethers.size() == 0 && isTetherProvisioningRequired(config)) {
|
||||
return false;
|
||||
|
||||
return isCellularUpstreamPermitted(config);
|
||||
}
|
||||
return mCellularUpstreamPermitted;
|
||||
|
||||
private boolean isCellularUpstreamPermitted(final TetheringConfiguration config) {
|
||||
if (!isTetherProvisioningRequired(config)) return true;
|
||||
|
||||
// If provisioning is required and EntitlementManager doesn't know any downstreams,
|
||||
// cellular upstream should not be allowed.
|
||||
if (mCurrentDownstreams.isEmpty()) return false;
|
||||
|
||||
return mCurrentEntitlementResults.indexOfValue(TETHER_ERROR_NO_ERROR) > -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,15 +169,11 @@ public class EntitlementManager {
|
||||
public void startProvisioningIfNeeded(int downstreamType, boolean showProvisioningUi) {
|
||||
if (!isValidDownstreamType(downstreamType)) return;
|
||||
|
||||
if (!mCurrentTethers.contains(downstreamType)) mCurrentTethers.add(downstreamType);
|
||||
mCurrentDownstreams.set(downstreamType, true);
|
||||
|
||||
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
|
||||
if (isTetherProvisioningRequired(config)) {
|
||||
// If provisioning is required and the result is not available yet,
|
||||
// cellular upstream should not be allowed.
|
||||
if (mCellularPermitted.size() == 0) {
|
||||
mCellularUpstreamPermitted = false;
|
||||
}
|
||||
if (!isTetherProvisioningRequired(config)) return;
|
||||
|
||||
// If upstream is not cellular, provisioning app would not be launched
|
||||
// till upstream change to cellular.
|
||||
if (mUsingCellularAsUpstream) {
|
||||
@@ -185,9 +186,6 @@ public class EntitlementManager {
|
||||
} else {
|
||||
mNeedReRunProvisioningUi |= showProvisioningUi;
|
||||
}
|
||||
} else {
|
||||
mCellularUpstreamPermitted = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,14 +193,14 @@ public class EntitlementManager {
|
||||
*
|
||||
* @param type tethering type from TetheringManager.TETHERING_{@code *}
|
||||
*/
|
||||
public void stopProvisioningIfNeeded(int type) {
|
||||
if (!isValidDownstreamType(type)) return;
|
||||
public void stopProvisioningIfNeeded(int downstreamType) {
|
||||
if (!isValidDownstreamType(downstreamType)) return;
|
||||
|
||||
mCurrentTethers.remove(type);
|
||||
mCurrentDownstreams.set(downstreamType, false);
|
||||
// There are lurking bugs where the notion of "provisioning required" or
|
||||
// "tethering supported" may change without without tethering being notified properly.
|
||||
// Remove the mapping all the time no matter provisioning is required or not.
|
||||
removeDownstreamMapping(type);
|
||||
removeDownstreamMapping(downstreamType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,7 +211,7 @@ public class EntitlementManager {
|
||||
public void notifyUpstream(boolean isCellular) {
|
||||
if (DBG) {
|
||||
mLog.i("notifyUpstream: " + isCellular
|
||||
+ ", mCellularUpstreamPermitted: " + mCellularUpstreamPermitted
|
||||
+ ", mLastCellularUpstreamPermitted: " + mLastCellularUpstreamPermitted
|
||||
+ ", mNeedReRunProvisioningUi: " + mNeedReRunProvisioningUi);
|
||||
}
|
||||
mUsingCellularAsUpstream = isCellular;
|
||||
@@ -231,7 +229,7 @@ public class EntitlementManager {
|
||||
}
|
||||
|
||||
private void maybeRunProvisioning(final TetheringConfiguration config) {
|
||||
if (mCurrentTethers.size() == 0 || !isTetherProvisioningRequired(config)) {
|
||||
if (mCurrentDownstreams.isEmpty() || !isTetherProvisioningRequired(config)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -239,8 +237,9 @@ public class EntitlementManager {
|
||||
// are allowed. Therefore even if the silent check here ends in a failure and the UI later
|
||||
// yields success, then the downstream that got a failure will re-evaluate as a result of
|
||||
// the change and get the new correct value.
|
||||
for (Integer downstream : mCurrentTethers) {
|
||||
if (mCellularPermitted.indexOfKey(downstream) < 0) {
|
||||
for (int downstream = mCurrentDownstreams.nextSetBit(0); downstream >= 0;
|
||||
downstream = mCurrentDownstreams.nextSetBit(downstream + 1)) {
|
||||
if (mCurrentEntitlementResults.indexOfKey(downstream) < 0) {
|
||||
if (mNeedReRunProvisioningUi) {
|
||||
mNeedReRunProvisioningUi = false;
|
||||
runUiTetherProvisioning(downstream, config.activeDataSubId);
|
||||
@@ -286,7 +285,7 @@ public class EntitlementManager {
|
||||
mLog.log("reevaluateSimCardProvisioning() don't run in TetherMaster thread");
|
||||
}
|
||||
mEntitlementCacheValue.clear();
|
||||
mCellularPermitted.clear();
|
||||
mCurrentEntitlementResults.clear();
|
||||
|
||||
// TODO: refine provisioning check to isTetherProvisioningRequired() ??
|
||||
if (!config.hasMobileHotspotProvisionApp()
|
||||
@@ -410,22 +409,21 @@ public class EntitlementManager {
|
||||
}
|
||||
|
||||
private void evaluateCellularPermission(final TetheringConfiguration config) {
|
||||
final boolean oldPermitted = mCellularUpstreamPermitted;
|
||||
mCellularUpstreamPermitted = (!isTetherProvisioningRequired(config)
|
||||
|| mCellularPermitted.indexOfValue(TETHER_ERROR_NO_ERROR) > -1);
|
||||
final boolean oldPermitted = mLastCellularUpstreamPermitted;
|
||||
mLastCellularUpstreamPermitted = isCellularUpstreamPermitted(config);
|
||||
|
||||
if (DBG) {
|
||||
mLog.i("Cellular permission change from " + oldPermitted
|
||||
+ " to " + mCellularUpstreamPermitted);
|
||||
+ " to " + mLastCellularUpstreamPermitted);
|
||||
}
|
||||
|
||||
if (mCellularUpstreamPermitted != oldPermitted) {
|
||||
mLog.log("Cellular permission change: " + mCellularUpstreamPermitted);
|
||||
if (mLastCellularUpstreamPermitted != oldPermitted) {
|
||||
mLog.log("Cellular permission change: " + mLastCellularUpstreamPermitted);
|
||||
mTetherMasterSM.sendMessage(mPermissionChangeMessageCode);
|
||||
}
|
||||
// Only schedule periodic re-check when tether is provisioned
|
||||
// and the result is ok.
|
||||
if (mCellularUpstreamPermitted && mCellularPermitted.size() > 0) {
|
||||
if (mLastCellularUpstreamPermitted && mCurrentEntitlementResults.size() > 0) {
|
||||
scheduleProvisioningRechecks(config);
|
||||
} else {
|
||||
cancelTetherProvisioningRechecks();
|
||||
@@ -441,10 +439,10 @@ public class EntitlementManager {
|
||||
*/
|
||||
protected void addDownstreamMapping(int type, int resultCode) {
|
||||
mLog.i("addDownstreamMapping: " + type + ", result: " + resultCode
|
||||
+ " ,TetherTypeRequested: " + mCurrentTethers.contains(type));
|
||||
if (!mCurrentTethers.contains(type)) return;
|
||||
+ " ,TetherTypeRequested: " + mCurrentDownstreams.get(type));
|
||||
if (!mCurrentDownstreams.get(type)) return;
|
||||
|
||||
mCellularPermitted.put(type, resultCode);
|
||||
mCurrentEntitlementResults.put(type, resultCode);
|
||||
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
|
||||
evaluateCellularPermission(config);
|
||||
}
|
||||
@@ -455,7 +453,7 @@ public class EntitlementManager {
|
||||
*/
|
||||
protected void removeDownstreamMapping(int type) {
|
||||
mLog.i("removeDownstreamMapping: " + type);
|
||||
mCellularPermitted.delete(type);
|
||||
mCurrentEntitlementResults.delete(type);
|
||||
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
|
||||
evaluateCellularPermission(config);
|
||||
}
|
||||
@@ -488,14 +486,15 @@ public class EntitlementManager {
|
||||
* @param pw {@link PrintWriter} is used to print formatted
|
||||
*/
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.print("mCellularUpstreamPermitted: ");
|
||||
pw.println(mCellularUpstreamPermitted);
|
||||
for (Integer type : mCurrentTethers) {
|
||||
pw.print("isCellularUpstreamPermitted: ");
|
||||
pw.println(isCellularUpstreamPermitted());
|
||||
for (int type = mCurrentDownstreams.nextSetBit(0); type >= 0;
|
||||
type = mCurrentDownstreams.nextSetBit(type + 1)) {
|
||||
pw.print("Type: ");
|
||||
pw.print(typeString(type));
|
||||
if (mCellularPermitted.indexOfKey(type) > -1) {
|
||||
if (mCurrentEntitlementResults.indexOfKey(type) > -1) {
|
||||
pw.print(", Value: ");
|
||||
pw.println(errorString(mCellularPermitted.get(type)));
|
||||
pw.println(errorString(mCurrentEntitlementResults.get(type)));
|
||||
} else {
|
||||
pw.println(", Value: empty");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user