Skip to content
Snippets Groups Projects
Commit 581afa0b authored by Mark Chien's avatar Mark Chien Committed by Gerrit Code Review
Browse files

Merge "Refactor the EntitlementManager"

parents 3a22b81c 33d861e6
No related branches found
No related tags found
No related merge requests found
......@@ -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 mCellularUpstreamPermitted;
return isCellularUpstreamPermitted(config);
}
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,29 +169,22 @@ 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 upstream is not cellular, provisioning app would not be launched
// till upstream change to cellular.
if (mUsingCellularAsUpstream) {
if (showProvisioningUi) {
runUiTetherProvisioning(downstreamType, config.activeDataSubId);
} else {
runSilentTetherProvisioning(downstreamType, config.activeDataSubId);
}
mNeedReRunProvisioningUi = false;
if (!isTetherProvisioningRequired(config)) return;
// If upstream is not cellular, provisioning app would not be launched
// till upstream change to cellular.
if (mUsingCellularAsUpstream) {
if (showProvisioningUi) {
runUiTetherProvisioning(downstreamType, config.activeDataSubId);
} else {
mNeedReRunProvisioningUi |= showProvisioningUi;
runSilentTetherProvisioning(downstreamType, config.activeDataSubId);
}
mNeedReRunProvisioningUi = false;
} else {
mCellularUpstreamPermitted = true;
mNeedReRunProvisioningUi |= showProvisioningUi;
}
}
......@@ -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");
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment