Fix entitlement check results

Adjust entitlement check results based on internal discussion.
Added documentation detailing the relationship between entitlement
status and provision status.
Also add/fix logs.

Test: atest SlicePurchaseControllerTest, CTS, manual
Bug: 277703187
Change-Id: Ia6fcb2815deeea33007cdba5b670e65056d50f30
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index d9dd3bf..6e6f799 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -2240,7 +2240,7 @@
                         arg.callback.accept(result);
                         log("purchasePremiumCapability: capability="
                                 + TelephonyManager.convertPremiumCapabilityToString(arg.capability)
-                                + ", result= "
+                                + ", result="
                                 + TelephonyManager.convertPurchaseResultToString(result));
                     } catch (RemoteException e) {
                         String logStr = "Purchase premium capability "
@@ -11642,7 +11642,7 @@
             if (processes != null) {
                 for (ActivityManager.RunningAppProcessInfo process : processes) {
                     log("purchasePremiumCapability: process " + process.processName
-                            + "has importance " + process.importance);
+                            + " has importance " + process.importance);
                     if (process.processName.equals(callingProcess) && process.importance
                             <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
                         isVisible = true;
diff --git a/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java b/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java
index 8288c43..d5ef816 100644
--- a/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java
+++ b/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java
@@ -160,7 +160,8 @@
             reportAnomaly(UUID_ENTITLEMENT_CHECK_UNEXPECTED_ERROR,
                     "checkEntitlementStatus failed with NumberFormatException");
         }
-
+        Log.d(TAG, "queryEntitlementStatus succeeded with response: "
+                + premiumNetworkEntitlementResponse);
         return premiumNetworkEntitlementResponse;
     }
 
diff --git a/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java b/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
index 242ca69..ba44581 100644
--- a/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
+++ b/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
@@ -22,6 +22,22 @@
 /**
  * Response class containing the entitlement status, provisioning status, and service flow URL
  * for premium network entitlement checks.
+ *
+ * The relationship between entitlement status (left column) and provision status (top row)
+ * is defined in the table below:
+ * +--------------+-----------------+-------------------+-------------------+---------------+
+ * |              | Not Provisioned |    Provisioned    |   Not Available   |  In Progress  |
+ * +--------------+-----------------+-------------------+-------------------+---------------+
+ * |   Disabled   |   Check failed  |    Check failed   |    Check failed   |  Check failed |
+ * +--------------+-----------------+-------------------+-------------------+---------------+
+ * |    Enabled   |  Carrier error  |  Display webview  |  Display webview  | Carrier error |
+ * +--------------+-----------------+-------------------+-------------------+---------------+
+ * | Incompatible |   Check failed  |    Check failed   |    Check failed   |  Check failed |
+ * +--------------+-----------------+-------------------+-------------------+---------------+
+ * | Provisioning |  Carrier error  |   Carrier error   |    In Progress    |  In Progress  |
+ * +--------------+-----------------+-------------------+-------------------+---------------+
+ * |   Included   |  Carrier error  | Already purchased | Already purchased | Carrier error |
+ * +--------------+-----------------+-------------------+-------------------+---------------+
  */
 public class PremiumNetworkEntitlementResponse {
     public static final int PREMIUM_NETWORK_ENTITLEMENT_STATUS_DISABLED = 0;
@@ -61,9 +77,8 @@
      * @return {@code true} if the premium network is provisioned and {@code false} otherwise.
      */
     public boolean isProvisioned() {
-        return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED
-                || mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED
-                || mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED;
+        return !isInvalidResponse()
+                && mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED;
     }
 
     /**
@@ -71,8 +86,8 @@
      *         {@code false} otherwise.
      */
     public boolean isProvisioningInProgress() {
-        return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS
-                || mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING;
+        return !isInvalidResponse()
+                && mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING;
     }
 
     /**
@@ -81,13 +96,33 @@
      */
     public boolean isPremiumNetworkCapabilityAllowed() {
         switch (mEntitlementStatus) {
+            case PREMIUM_NETWORK_ENTITLEMENT_STATUS_DISABLED:
             case PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCOMPATIBLE:
                 return false;
         }
-        switch (mProvisionStatus) {
-            case PREMIUM_NETWORK_PROVISION_STATUS_NOT_AVAILABLE:
-                return false;
+        return !isInvalidResponse();
+    }
+
+    /**
+     * @return {@code true} if the response is invalid and {@code false} if it is valid.
+     */
+    public boolean isInvalidResponse() {
+        switch (mEntitlementStatus) {
+            case PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED:
+            case PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED:
+                return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED
+                        || mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS;
+            case PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING:
+                return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED
+                    || mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED;
         }
-        return true;
+        return false;
+    }
+
+    @Override
+    @NonNull public String toString() {
+        return "PremiumNetworkEntitlementResponse{mEntitlementStatus=" + mEntitlementStatus
+                + ", mProvisionStatus=" + mProvisionStatus + ", mServiceFlowURL=" + mServiceFlowURL
+                + ", mServiceFlowUserData" + mServiceFlowUserData + "}";
     }
 }
diff --git a/src/com/android/phone/slice/SlicePurchaseController.java b/src/com/android/phone/slice/SlicePurchaseController.java
index ef8780c..e7d6390 100644
--- a/src/com/android/phone/slice/SlicePurchaseController.java
+++ b/src/com/android/phone/slice/SlicePurchaseController.java
@@ -19,6 +19,7 @@
 import static android.telephony.TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_IN_PROGRESS;
 import static android.telephony.TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED;
 import static android.telephony.TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_DISABLED;
+import static android.telephony.TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR;
 import static android.telephony.TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_ENTITLEMENT_CHECK_FAILED;
 import static android.telephony.TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUBSCRIPTION;
 
@@ -695,8 +696,16 @@
                 premiumNetworkEntitlementApi.checkEntitlementStatus(capability);
 
         // invalid response for entitlement check
-        if (premiumNetworkEntitlementResponse == null) {
-            logd("Invalid response for entitlement check.");
+        if (premiumNetworkEntitlementResponse == null
+                || premiumNetworkEntitlementResponse.isInvalidResponse()) {
+            loge("Invalid response for entitlement check: " + premiumNetworkEntitlementResponse);
+            handlePurchaseResult(capability,
+                    PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR, true);
+            return;
+        }
+
+        if (!premiumNetworkEntitlementResponse.isPremiumNetworkCapabilityAllowed()) {
+            loge("Entitlement Check: Not allowed.");
             handlePurchaseResult(capability,
                     PURCHASE_PREMIUM_CAPABILITY_RESULT_ENTITLEMENT_CHECK_FAILED, true);
             return;
@@ -710,18 +719,12 @@
         }
 
         if (premiumNetworkEntitlementResponse.isProvisioningInProgress()) {
-            logd("Entitlement Check: In Progress");
+            logd("Entitlement Check: In progress.");
             handlePurchaseResult(capability,
                     PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_IN_PROGRESS, true);
             return;
         }
 
-        if (!premiumNetworkEntitlementResponse.isPremiumNetworkCapabilityAllowed()) {
-            handlePurchaseResult(capability,
-                    PURCHASE_PREMIUM_CAPABILITY_RESULT_ENTITLEMENT_CHECK_FAILED, true);
-            return;
-        }
-
         String purchaseUrl = getPurchaseUrl(premiumNetworkEntitlementResponse);
         String carrier = getSimOperator();
         if (TextUtils.isEmpty(purchaseUrl) || TextUtils.isEmpty(carrier)) {