diff options
author | danielwbhuang <danielwbhuang@google.com> | 2021-06-09 16:42:54 +0800 |
---|---|---|
committer | danielwbhuang <danielwbhuang@google.com> | 2021-06-10 18:45:49 +0800 |
commit | 8e4f866f12637d56d074beeccbc49ad5f8a1fe0c (patch) | |
tree | d9144ab8a448fc561b825322fc6444d99fdf8a8c | |
parent | be98b84f1b16b438c946e5d49f6dcafe642a2c48 (diff) | |
download | ImsServiceEntitlement-8e4f866f12637d56d074beeccbc49ad5f8a1fe0c.tar.gz |
Monitor VERS.validity expiry.
1. if ClientBehavior is VALID_DURING_VALIDITY and validity is expired, it should requery the entitlement status.
2. if ClientBehavior is NEEDS_TO_RESET, NEEDS_TO_RESET_EXCEPT_VERS, NEEDS_TO_RESET_EXCEPT_VERS_UNTIL_SETTING_ON or UNKNOWN_BEHAVIOR, it should reset the data to the default configuration.
Test: make
Bug: 170788440
Change-Id: Icbcf5d350d94dd1a042f4d0b5641f1d87690d5ca
5 files changed, 179 insertions, 69 deletions
diff --git a/src/com/android/imsserviceentitlement/ImsEntitlementApi.java b/src/com/android/imsserviceentitlement/ImsEntitlementApi.java index 4d3af07..98d9de6 100644 --- a/src/com/android/imsserviceentitlement/ImsEntitlementApi.java +++ b/src/com/android/imsserviceentitlement/ImsEntitlementApi.java @@ -23,6 +23,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.imsserviceentitlement.entitlement.EntitlementConfiguration; +import com.android.imsserviceentitlement.entitlement.EntitlementConfiguration.ClientBehavior; import com.android.imsserviceentitlement.entitlement.EntitlementResult; import com.android.imsserviceentitlement.fcm.FcmTokenStore; import com.android.imsserviceentitlement.fcm.FcmUtils; @@ -96,6 +97,10 @@ public class ImsEntitlementApi { requestBuilder.setTerminalModel("modelY"); requestBuilder.setTerminalSoftwareVersion("versionZ"); requestBuilder.setAcceptContentType(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_XML); + if (mNeedsImsProvisioning) { + mLastEntitlementConfiguration.getVersion().ifPresent( + version -> requestBuilder.setConfigurationVersion(Integer.parseInt(version))); + } ServiceEntitlementRequest request = requestBuilder.build(); XmlDoc entitlementXmlDoc = null; @@ -132,25 +137,43 @@ public class ImsEntitlementApi { return entitlementXmlDoc == null ? null : toEntitlementResult(entitlementXmlDoc); } - private static EntitlementResult toEntitlementResult(XmlDoc doc) { - EntitlementResult.Builder builder = - EntitlementResult.builder() - .setVowifiStatus(Ts43VowifiStatus.builder(doc).build()) - .setVolteStatus(Ts43VolteStatus.builder(doc).build()) - .setSmsoveripStatus(Ts43SmsOverIpStatus.builder(doc).build()); - doc.get( - ResponseXmlNode.APPLICATION, - ResponseXmlAttributes.SERVER_FLOW_URL, - ServiceEntitlement.APP_VOWIFI) - .ifPresent(url -> builder.setEmergencyAddressWebUrl(url)); - doc.get( - ResponseXmlNode.APPLICATION, - ResponseXmlAttributes.SERVER_FLOW_USER_DATA, - ServiceEntitlement.APP_VOWIFI) - .ifPresent(userData -> builder.setEmergencyAddressWebData(userData)); + private EntitlementResult toEntitlementResult(XmlDoc doc) { + EntitlementResult.Builder builder = EntitlementResult.builder(); + ClientBehavior clientBehavior = mLastEntitlementConfiguration.entitlementValidation(); + + if (mNeedsImsProvisioning && isResetToDefault(clientBehavior)) { + // keep the entitlement result in default value and reset the configs. + if (clientBehavior == ClientBehavior.NEEDS_TO_RESET + || clientBehavior == ClientBehavior.UNKNOWN_BEHAVIOR) { + mLastEntitlementConfiguration.reset(); + } else { + mLastEntitlementConfiguration.resetConfigsExceptVers(); + } + } else { + builder.setVowifiStatus(Ts43VowifiStatus.builder(doc).build()) + .setVolteStatus(Ts43VolteStatus.builder(doc).build()) + .setSmsoveripStatus(Ts43SmsOverIpStatus.builder(doc).build()); + doc.get( + ResponseXmlNode.APPLICATION, + ResponseXmlAttributes.SERVER_FLOW_URL, + ServiceEntitlement.APP_VOWIFI) + .ifPresent(url -> builder.setEmergencyAddressWebUrl(url)); + doc.get( + ResponseXmlNode.APPLICATION, + ResponseXmlAttributes.SERVER_FLOW_USER_DATA, + ServiceEntitlement.APP_VOWIFI) + .ifPresent(userData -> builder.setEmergencyAddressWebData(userData)); + } return builder.build(); } + private boolean isResetToDefault(ClientBehavior clientBehavior) { + return clientBehavior == ClientBehavior.UNKNOWN_BEHAVIOR + || clientBehavior == ClientBehavior.NEEDS_TO_RESET + || clientBehavior == ClientBehavior.NEEDS_TO_RESET_EXCEPT_VERS + || clientBehavior == ClientBehavior.NEEDS_TO_RESET_EXCEPT_VERS_UNTIL_SETTING_ON; + } + private CarrierConfig getCarrierConfig(Context context) { String entitlementServiceUrl = TelephonyUtils.getEntitlementServerUrl(context, mSubId); return CarrierConfig.builder().setServerUrl(entitlementServiceUrl).build(); diff --git a/src/com/android/imsserviceentitlement/ImsEntitlementPollingService.java b/src/com/android/imsserviceentitlement/ImsEntitlementPollingService.java index f35503b..3cb748b 100644 --- a/src/com/android/imsserviceentitlement/ImsEntitlementPollingService.java +++ b/src/com/android/imsserviceentitlement/ImsEntitlementPollingService.java @@ -42,11 +42,15 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.annotation.WorkerThread; +import com.android.imsserviceentitlement.entitlement.EntitlementConfiguration; +import com.android.imsserviceentitlement.entitlement.EntitlementConfiguration.ClientBehavior; import com.android.imsserviceentitlement.entitlement.EntitlementResult; import com.android.imsserviceentitlement.job.JobManager; import com.android.imsserviceentitlement.utils.ImsUtils; import com.android.imsserviceentitlement.utils.TelephonyUtils; +import java.time.Duration; + /** * The {@link JobService} for querying entitlement status in the background. The jobId is unique for * different subId + job combination, so can run the same job for different subIds w/o cancelling @@ -89,6 +93,15 @@ public class ImsEntitlementPollingService extends JobService { .queryEntitlementStatusOnceNetworkReady(retryCount); } + /** Enqueues a job to query entitlement status with delay. */ + private static void enqueueJobWithDelay(Context context, int subId, long delayInSeconds) { + JobManager.getInstance( + context, + COMPONENT_NAME, + subId) + .queryEntitlementStatusOnceNetworkReady(0, Duration.ofSeconds(delayInSeconds)); + } + @Override public boolean onStartJob(final JobParameters params) { PersistableBundle bundle = params.getExtras(); @@ -185,7 +198,9 @@ public class ImsEntitlementPollingService extends JobService { private void doEntitlementCheck() { if (mNeedsImsProvisioning) { + // TODO(b/190476343): Unify EntitlementResult and EntitlementConfiguration. doImsEntitlementCheck(); + checkVersValidity(); } else { doWfcEntitlementCheck(); } @@ -250,6 +265,22 @@ public class ImsEntitlementPollingService extends JobService { } /** + * Schedules entitlement status check after a VERS.validity time, if the last valid is + * during validity. + */ + private void checkVersValidity() { + EntitlementConfiguration lastEntitlementConfiguration = + new EntitlementConfiguration(ImsEntitlementPollingService.this, mSubid); + if (lastEntitlementConfiguration.entitlementValidation() + == ClientBehavior.VALID_DURING_VALIDITY) { + enqueueJobWithDelay( + ImsEntitlementPollingService.this, + mSubid, + lastEntitlementConfiguration.getVersValidity()); + } + } + + /** * Returns {@code true} when {@code EntitlementResult} says WFC is not activated; Otherwise * {@code false} if {@code EntitlementResult} is not of any known pattern. */ diff --git a/src/com/android/imsserviceentitlement/entitlement/EntitlementConfiguration.java b/src/com/android/imsserviceentitlement/entitlement/EntitlementConfiguration.java index 7617cc6..ce18d86 100644 --- a/src/com/android/imsserviceentitlement/entitlement/EntitlementConfiguration.java +++ b/src/com/android/imsserviceentitlement/entitlement/EntitlementConfiguration.java @@ -131,6 +131,24 @@ public class EntitlementConfiguration { .orElse(DEFAULT_VALIDITY); } + /** Returns version stored in the {@link EntitlementCharacteristicDataStore}. */ + public Optional<String> getVersion() { + return mXmlDoc.get(ResponseXmlNode.VERS, ResponseXmlAttributes.VERSION, null); + } + + /** + * Returns the validity of the version, in seconds. The validity is counted from the time it is + * received by the client. If no data exist then returns default value 0. + */ + public long getVersValidity() { + return mXmlDoc.get( + ResponseXmlNode.VERS, + ResponseXmlAttributes.VALIDITY, + null) + .map(Long::parseLong) + .orElse(DEFAULT_VALIDITY); + } + public enum ClientBehavior { /** Unknown behavior. */ UNKNOWN_BEHAVIOR, @@ -205,4 +223,32 @@ public class EntitlementConfiguration { // - SMSoIP.EntitlementStatus=2 (INCOMPATIBLE_STATE) update(null); } + + /** Reverts to the default configurations except the version and validity. */ + public void resetConfigsExceptVers() { + String rawXml = + "<wap-provisioningdoc version=\"1.1\">" + + " <characteristic type=\"VERS\">" + + " <parm name=\"version\" value=\"" + getVersion() + "\"/>" + + " <parm name=\"validity\" value=\"" + getVersValidity() + "\"/>" + + " </characteristic>" + + " <characteristic type=\"TOKEN\">" + + " <parm name=\"token\" value=\"\"/>" + + " <parm name=\"validity\" value=\"0\"/>" + + " </characteristic>" + + " <characteristic type=\"APPLICATION\">" + + " <parm name=\"AppID\" value=\"ap2003\"/>" + + " <parm name=\"EntitlementStatus\" value=\"2\"/>" + + " </characteristic>" + + " <characteristic type=\"APPLICATION\">" + + " <parm name=\"AppID\" value=\"ap2004\"/>" + + " <parm name=\"EntitlementStatus\" value=\"2\"/>" + + " </characteristic>" + + " <characteristic type=\"APPLICATION\">" + + " <parm name=\"AppID\" value=\"ap2005\"/>" + + " <parm name=\"EntitlementStatus\" value=\"2\"/>" + + " </characteristic>" + + "</wap-provisioningdoc>"; + update(rawXml); + } } diff --git a/src/com/android/imsserviceentitlement/job/JobManager.java b/src/com/android/imsserviceentitlement/job/JobManager.java index b314ec1..4bbc5d6 100644 --- a/src/com/android/imsserviceentitlement/job/JobManager.java +++ b/src/com/android/imsserviceentitlement/job/JobManager.java @@ -30,6 +30,8 @@ import androidx.annotation.GuardedBy; import com.android.imsserviceentitlement.utils.TelephonyUtils; +import java.time.Duration; + /** Manages all scheduled jobs and provides common job scheduler. */ public class JobManager { private static final String TAG = "IMSSE-JobManager"; @@ -111,21 +113,29 @@ public class JobManager { builder.setExtras(bundle); } - /** Checks Entitlement Status once has network connection. */ + /** Checks Entitlement Status once has network connection without retry and delay. */ public void queryEntitlementStatusOnceNetworkReady() { - queryEntitlementStatusOnceNetworkReady(0 /* retryCount */); + queryEntitlementStatusOnceNetworkReady(/* retryCount= */ 0, Duration.ofSeconds(0)); } /** Checks Entitlement Status once has network connection with retry count. */ public void queryEntitlementStatusOnceNetworkReady(int retryCount) { + queryEntitlementStatusOnceNetworkReady(retryCount, Duration.ofSeconds(0)); + } + + /** Checks Entitlement Status once has network connection with retry count and delay. */ + public void queryEntitlementStatusOnceNetworkReady(int retryCount, Duration delay) { Log.d( TAG, "schedule QUERY_ENTITLEMENT_STATUS_JOB_ID once has network connection, " + "retryCount=" - + retryCount); + + retryCount + + ", delay=" + + delay); JobInfo job = newJobInfoBuilder(QUERY_ENTITLEMENT_STATUS_JOB_ID, retryCount) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + .setMinimumLatency(delay.toMillis()) .build(); mJobScheduler.schedule(job); } diff --git a/tests/unittests/src/com/android/imsserviceentitlement/ImsEntitlementApiTest.java b/tests/unittests/src/com/android/imsserviceentitlement/ImsEntitlementApiTest.java index 9db46d5..991f76d 100644 --- a/tests/unittests/src/com/android/imsserviceentitlement/ImsEntitlementApiTest.java +++ b/tests/unittests/src/com/android/imsserviceentitlement/ImsEntitlementApiTest.java @@ -66,59 +66,59 @@ public class ImsEntitlementApiTest { private static final int SUB_ID = 1; private static final String FCM_TOKEN = "FCM_TOKEN"; private static final String RAW_XML = - "<wap-provisioningdoc version=\"1.1\">\n" - + " <characteristic type=\"VERS\">\n" - + " <parm name=\"version\" value=\"1\"/>\n" - + " <parm name=\"validity\" value=\"1728000\"/>\n" - + " </characteristic>\n" - + " <characteristic type=\"TOKEN\">\n" - + " <parm name=\"token\" value=\"kZYfCEpSsMr88KZVmab5UsZVzl+nWSsX\"/>\n" - + " <parm name=\"validity\" value=\"3600\"/>\n" - + " </characteristic>\n" - + " <characteristic type=\"APPLICATION\">\n" - + " <parm name=\"AppID\" value=\"ap2004\"/>\n" - + " <parm name=\"EntitlementStatus\" value=\"1\"/>\n" - + " </characteristic>\n" - + "</wap-provisioningdoc>\n"; + "<wap-provisioningdoc version=\"1.1\">" + + " <characteristic type=\"VERS\">" + + " <parm name=\"version\" value=\"1\"/>" + + " <parm name=\"validity\" value=\"1728000\"/>" + + " </characteristic>" + + " <characteristic type=\"TOKEN\">" + + " <parm name=\"token\" value=\"kZYfCEpSsMr88KZVmab5UsZVzl+nWSsX\"/>" + + " <parm name=\"validity\" value=\"3600\"/>" + + " </characteristic>" + + " <characteristic type=\"APPLICATION\">" + + " <parm name=\"AppID\" value=\"ap2004\"/>" + + " <parm name=\"EntitlementStatus\" value=\"1\"/>" + + " </characteristic>" + + "</wap-provisioningdoc>"; private static final String RAW_XML_NEW_TOKEN = - "<wap-provisioningdoc version=\"1.1\">\n" - + " <characteristic type=\"VERS\">\n" - + " <parm name=\"version\" value=\"1\"/>\n" - + " <parm name=\"validity\" value=\"1728000\"/>\n" - + " </characteristic>\n" - + " <characteristic type=\"TOKEN\">\n" - + " <parm name=\"token\" value=\"NEW_TOKEN\"/>\n" - + " <parm name=\"validity\" value=\"3600\"/>\n" - + " </characteristic>\n" - + " <characteristic type=\"APPLICATION\">\n" - + " <parm name=\"AppID\" value=\"ap2004\"/>\n" - + " <parm name=\"EntitlementStatus\" value=\"1\"/>\n" - + " </characteristic>\n" - + "</wap-provisioningdoc>\n"; + "<wap-provisioningdoc version=\"1.1\">" + + " <characteristic type=\"VERS\">" + + " <parm name=\"version\" value=\"1\"/>" + + " <parm name=\"validity\" value=\"1728000\"/>" + + " </characteristic>" + + " <characteristic type=\"TOKEN\">" + + " <parm name=\"token\" value=\"NEW_TOKEN\"/>" + + " <parm name=\"validity\" value=\"3600\"/>" + + " </characteristic>\n" + + " <characteristic type=\"APPLICATION\">" + + " <parm name=\"AppID\" value=\"ap2004\"/>" + + " <parm name=\"EntitlementStatus\" value=\"1\"/>" + + " </characteristic>" + + "</wap-provisioningdoc>"; private static final String MULTIPLE_APPIDS_RAW_XML = - "<wap-provisioningdoc version=\"1.1\">\n" - + " <characteristic type=\"VERS\">\n" - + " <parm name=\"version\" value=\"1\"/>\n" - + " <parm name=\"validity\" value=\"1728000\"/>\n" - + " </characteristic>\n" - + " <characteristic type=\"TOKEN\">\n" - + " <parm name=\"token\" value=\"kZYfCEpSsMr88KZVmab5UsZVzl+nWSsX\"/>\n" - + " <parm name=\"validity\" value=\"3600\"/>\n" - + " </characteristic>\n" - + " <characteristic type=\"APPLICATION\">\n" - + " <parm name=\"AppID\" value=\"ap2003\"/>\n" - + " <parm name=\"EntitlementStatus\" value=\"1\"/>\n" - + " </characteristic>\n" - + " <characteristic type=\"APPLICATION\">\n" - + " <parm name=\"AppID\" value=\"ap2004\"/>\n" - + " <parm name=\"EntitlementStatus\" value=\"1\"/>\n" - + " </characteristic>\n" - + " <characteristic type=\"APPLICATION\">\n" - + " <parm name=\"AppID\" value=\"ap2005\"/>\n" - + " <parm name=\"EntitlementStatus\" value=\"1\"/>\n" - + " </characteristic>\n" - + "</wap-provisioningdoc>\n"; + "<wap-provisioningdoc version=\"1.1\">" + + " <characteristic type=\"VERS\">" + + " <parm name=\"version\" value=\"1\"/>" + + " <parm name=\"validity\" value=\"1728000\"/>" + + " </characteristic>" + + " <characteristic type=\"TOKEN\">" + + " <parm name=\"token\" value=\"kZYfCEpSsMr88KZVmab5UsZVzl+nWSsX\"/>" + + " <parm name=\"validity\" value=\"3600\"/>" + + " </characteristic>" + + " <characteristic type=\"APPLICATION\">" + + " <parm name=\"AppID\" value=\"ap2003\"/>" + + " <parm name=\"EntitlementStatus\" value=\"1\"/>" + + " </characteristic>\n" + + " <characteristic type=\"APPLICATION\">" + + " <parm name=\"AppID\" value=\"ap2004\"/>\n" + + " <parm name=\"EntitlementStatus\" value=\"1\"/>" + + " </characteristic>" + + " <characteristic type=\"APPLICATION\">" + + " <parm name=\"AppID\" value=\"ap2005\"/>" + + " <parm name=\"EntitlementStatus\" value=\"1\"/>" + + " </characteristic>" + + "</wap-provisioningdoc>"; private final EntitlementConfiguration mEntitlementConfiguration = new EntitlementConfiguration(ApplicationProvider.getApplicationContext(), SUB_ID); |