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