1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.libraries.entitlement; 18 19 /** 20 * Indicates errors happened in retrieving service entitlement configuration. 21 */ 22 public class ServiceEntitlementException extends Exception { 23 /** 24 * Unknown error. 25 */ 26 public static final int ERROR_UNKNOWN = 0; 27 28 // Android telephony related failures 29 /** 30 * Android telephony is unable to provide info like IMSI, e.g. when modem crashed. 31 */ 32 public static final int ERROR_PHONE_NOT_AVAILABLE = 10; 33 34 // EAP-AKA authentication related falures 35 /** 36 * SIM not returning a response to the EAP-AKA challenge, e.g. when the challenge is invalid. 37 * This can happen only when an embedded EAP-AKA challange is conducted, as per GMSA spec TS.43 38 * section 2.6.1. 39 */ 40 public static final int ERROR_ICC_AUTHENTICATION_NOT_AVAILABLE = 20; 41 /** 42 * EAP-AKA synchronization failure that cannot be recoverd even after the "Sequence number 43 * synchronization" procedure as defined in RFC 4187. 44 */ 45 public static final int ERROR_EAP_AKA_SYNCHRONIZATION_FAILURE = 21; 46 /** 47 * EAP-AKA failure that happens when the client fails to authenticate within the maximum number 48 * of attempts 49 */ 50 public static final int ERROR_EAP_AKA_FAILURE = 21; 51 52 // HTTP related failures 53 /** 54 * Cannot connect to the entitlment server, e.g. due to weak mobile network and Wi-Fi 55 * connection. 56 */ 57 public static final int ERROR_SERVER_NOT_CONNECTABLE = 30; 58 /** 59 * HTTP response received with a status code indicating failure, e.g. 4xx and 5xx. Use {@link 60 * #getHttpStatus} to get the status code and {@link #getMessage} the error message in the 61 * response body. 62 */ 63 public static final int ERROR_HTTP_STATUS_NOT_SUCCESS = 31; 64 /** 65 * HTTP response received with a malformed format. e.g. the response with content-type JSON but 66 * failing JSON parser. 67 */ 68 public static final int ERROR_MALFORMED_HTTP_RESPONSE = 32; 69 70 /** 71 * Default HTTP status if not been specified. 72 */ 73 private static final int HTTP_STATUS_UNSPECIFIED = 0; 74 75 /** 76 * An empty string if Retry-After header in HTTP response not been specified. 77 */ 78 private static final String RETRY_AFTER_UNSPECIFIED = ""; 79 80 private int mError; 81 private int mHttpStatus; 82 private String mRetryAfter; 83 ServiceEntitlementException(int error, String message)84 public ServiceEntitlementException(int error, String message) { 85 this(error, HTTP_STATUS_UNSPECIFIED, RETRY_AFTER_UNSPECIFIED, message); 86 } 87 ServiceEntitlementException(int error, int httpStatus, String message)88 public ServiceEntitlementException(int error, int httpStatus, String message) { 89 this(error, httpStatus, RETRY_AFTER_UNSPECIFIED, message); 90 } 91 ServiceEntitlementException( int error, int httpStatus, String retryAfter, String message)92 public ServiceEntitlementException( 93 int error, int httpStatus, String retryAfter, String message) { 94 super(message); 95 this.mError = error; 96 this.mHttpStatus = httpStatus; 97 this.mRetryAfter = retryAfter; 98 } 99 ServiceEntitlementException(int error, String message, Throwable cause)100 public ServiceEntitlementException(int error, String message, Throwable cause) { 101 this(error, HTTP_STATUS_UNSPECIFIED, RETRY_AFTER_UNSPECIFIED, message, cause); 102 } 103 ServiceEntitlementException(int error, int httpStatus, String message, Throwable cause)104 public ServiceEntitlementException(int error, int httpStatus, String message, Throwable cause) { 105 this(error, httpStatus, RETRY_AFTER_UNSPECIFIED, message, cause); 106 } 107 ServiceEntitlementException( int error, int httpStatus, String retryAfter, String message, Throwable cause)108 public ServiceEntitlementException( 109 int error, int httpStatus, String retryAfter, String message, Throwable cause) { 110 super(message, cause); 111 this.mError = error; 112 this.mHttpStatus = httpStatus; 113 this.mRetryAfter = retryAfter; 114 } 115 116 /** 117 * Returns the error code, see {@link #ERROR_*}. {@link #ERROR_UNKNOWN} if not been specified. 118 */ getErrorCode()119 public int getErrorCode() { 120 return mError; 121 } 122 123 /** 124 * Returns the HTTP status code returned by entitlement server; {@link #HTTP_STATUS_UNSPECIFIED} 125 * if not been specified. 126 */ getHttpStatus()127 public int getHttpStatus() { 128 return mHttpStatus; 129 } 130 131 /** 132 * Returns the "Retry-After" header in HTTP response, often set with HTTP status code 503; an 133 * empty string if unavailable. 134 * 135 * @return the HTTP-date or a number of seconds to delay, as defiend in RFC 7231: 136 * https://tools.ietf.org/html/rfc7231#section-7.1.3 137 */ getRetryAfter()138 public String getRetryAfter() { 139 return mRetryAfter; 140 } 141 } 142