1 package com.android.onboarding.contracts.authmanaged 2 3 import android.accounts.Account 4 import android.app.Activity 5 import android.content.Context 6 import android.content.Intent 7 import android.os.Build 8 import android.os.Bundle 9 import androidx.activity.result.ActivityResult 10 import androidx.annotation.RequiresApi 11 import com.android.onboarding.common.AUTH_MANAGED 12 import com.android.onboarding.contracts.ContractResult 13 import com.android.onboarding.contracts.NodeAwareIntentScope 14 import com.android.onboarding.contracts.NodeAwareIntentSerializer 15 import com.android.onboarding.contracts.NodeId 16 import com.android.onboarding.contracts.OnboardingActivityApiContract 17 import com.android.onboarding.contracts.OnboardingNodeId 18 import com.android.onboarding.contracts.annotations.OnboardingNode 19 import com.android.onboarding.contracts.setupwizard.SuwArguments 20 import com.android.onboarding.contracts.setupwizard.SuwArgumentsSerializer 21 import com.android.onboarding.contracts.setupwizard.WithSuwArguments 22 import javax.inject.Inject 23 24 // LINT.IfChange 25 const val UNMANAGED_WORK_PROFILE_MODE_UNSPECIFIED: Int = 0 26 27 // LINT.ThenChange(//depot/google3/java/com/google/android/gmscore/integ/libs/common_auth/src/com/google/android/gms/common/auth/ui/ManagedAccountUtil.java) 28 29 interface EmmArguments : WithSuwArguments { 30 val account: Account 31 val options: Bundle 32 val flow: Int? 33 val dmStatus: String? 34 val isSetupWizard: Boolean 35 val suppressDeviceManagement: Boolean 36 val callingPackage: String 37 val isMainUser: Boolean 38 val isUnicornAccount: Boolean 39 val unmanagedWorkProfileMode: Int 40 41 companion object { 42 @JvmStatic 43 @JvmName("of") invokenull44 operator fun invoke( 45 suwArguments: SuwArguments, 46 account: Account, 47 options: Bundle = Bundle.EMPTY, 48 flow: Int? = null, 49 dmStatus: String? = null, 50 isSetupWizard: Boolean = false, 51 suppressDeviceManagement: Boolean = false, 52 callingPackage: String = "", 53 isMainUser: Boolean = false, 54 isUnicornAccount: Boolean = false, 55 unmanagedWorkProfileMode: Int = UNMANAGED_WORK_PROFILE_MODE_UNSPECIFIED, 56 ): EmmArguments = 57 object : EmmArguments { 58 override val suwArguments = suwArguments 59 override val account = account 60 override val options = options 61 override val flow = flow 62 override val dmStatus = dmStatus 63 override val isSetupWizard = isSetupWizard 64 override val suppressDeviceManagement = suppressDeviceManagement 65 override val callingPackage = callingPackage 66 override val isMainUser = isMainUser 67 override val isUnicornAccount = isUnicornAccount 68 override val unmanagedWorkProfileMode = unmanagedWorkProfileMode 69 } 70 } 71 } 72 73 sealed interface EmmResult { 74 val code: Int 75 76 sealed interface Success : EmmResult { 77 data object OK : Success { 78 override val code = Activity.RESULT_OK 79 } 80 81 data class Unknown(override val code: Int) : Success 82 } 83 84 sealed interface Failure : EmmResult { 85 data object LaunchAppFailed : Failure { 86 override val code = RESULTS.RESULT_LAUNCH_APP_FAILED 87 } 88 89 data object FetchAppInfoFailed : Failure { 90 override val code = RESULTS.RESULT_FETCH_APP_INFO_FAILED 91 } 92 93 data object DownloadInstallFailed : Failure { 94 override val code = RESULTS.RESULT_DOWNLOAD_INSTALL_FAILED 95 } 96 97 data object DmNotSupported : Failure { 98 override val code = RESULTS.RESULT_DM_NOT_SUPPORTED 99 } 100 101 data object DownloadInstallCanceled : Failure { 102 override val code = RESULTS.RESULT_DOWNLOAD_INSTALL_CANCELED 103 } 104 105 data object ShouldSkipDm : Failure { 106 override val code = RESULTS.RESULT_SHOULD_SKIP_DM 107 } 108 109 data object SetupSuppressedByCaller : Failure { 110 override val code = RESULTS.RESULT_SETUP_SUPPRESSED_BY_CALLER 111 } 112 113 data object DisallowAddingManagedAccount : Failure { 114 override val code = RESULTS.RESULT_DISALLOW_ADDING_MANAGED_ACCOUNT 115 } 116 117 data object CancelledForceRemoveAccount : Failure { 118 override val code = RESULTS.RESULT_CANCELLED_FORCE_REMOVE_ACCOUNT 119 } 120 121 data object Cancelled : Failure { 122 override val code = Activity.RESULT_CANCELED 123 } 124 125 data class Unknown(override val code: Int) : Failure 126 } 127 } 128 129 /** 130 * Contract for {@link EmmChimeraActivity}. Note that the component of this contract intent is 131 * assumed to be set by the caller if launching via Component 132 */ 133 @OnboardingNode(component = AUTH_MANAGED, name = "Emm", uiType = OnboardingNode.UiType.INVISIBLE) 134 @RequiresApi(Build.VERSION_CODES.Q) 135 class EmmContract 136 @Inject 137 constructor( 138 @OnboardingNodeId override val nodeId: NodeId, 139 val suwArgumentsSerializer: SuwArgumentsSerializer, 140 ) : 141 OnboardingActivityApiContract<EmmArguments, EmmResult>(), 142 NodeAwareIntentSerializer<EmmArguments> { 143 performCreateIntentnull144 override fun performCreateIntent(context: Context, arg: EmmArguments): Intent = Intent(arg = arg) 145 146 override fun performExtractArgument(intent: Intent): EmmArguments = read(intent) 147 148 override fun performParseResult(result: ActivityResult): EmmResult = 149 when { 150 result.resultCode == RESULTS.RESULT_LAUNCH_APP_FAILED -> EmmResult.Failure.LaunchAppFailed 151 result.resultCode == RESULTS.RESULT_FETCH_APP_INFO_FAILED -> 152 EmmResult.Failure.FetchAppInfoFailed 153 result.resultCode == RESULTS.RESULT_DOWNLOAD_INSTALL_FAILED -> 154 EmmResult.Failure.DownloadInstallFailed 155 result.resultCode == RESULTS.RESULT_DM_NOT_SUPPORTED -> EmmResult.Failure.DmNotSupported 156 result.resultCode == RESULTS.RESULT_DOWNLOAD_INSTALL_CANCELED -> 157 EmmResult.Failure.DownloadInstallCanceled 158 result.resultCode == RESULTS.RESULT_SHOULD_SKIP_DM -> EmmResult.Failure.ShouldSkipDm 159 result.resultCode == RESULTS.RESULT_SETUP_SUPPRESSED_BY_CALLER -> 160 EmmResult.Failure.SetupSuppressedByCaller 161 result.resultCode == RESULTS.RESULT_DISALLOW_ADDING_MANAGED_ACCOUNT -> 162 EmmResult.Failure.DisallowAddingManagedAccount 163 result.resultCode == RESULTS.RESULT_CANCELLED_FORCE_REMOVE_ACCOUNT -> 164 EmmResult.Failure.CancelledForceRemoveAccount 165 result.resultCode == Activity.RESULT_CANCELED -> EmmResult.Failure.Cancelled 166 result.resultCode == Activity.RESULT_OK -> EmmResult.Success.OK 167 result.resultCode > 0 -> EmmResult.Success.Unknown(result.resultCode) 168 else -> EmmResult.Failure.Unknown(result.resultCode) 169 } 170 performSetResultnull171 override fun performSetResult(result: EmmResult): ActivityResult = 172 if (result is EmmResult.Success) { 173 ContractResult.Success(result.code) 174 } else { 175 ContractResult.Failure(result.code) 176 } 177 .toActivityResult() 178 writenull179 override fun NodeAwareIntentScope.write(value: EmmArguments) { 180 intent[suwArgumentsSerializer] = value::suwArguments 181 intent[EXTRAS.EXTRA_ACCOUNT] = value::account 182 intent[EXTRAS.EXTRA_IS_SETUP_WIZARD] = value::isSetupWizard 183 intent[EXTRAS.EXTRA_SUPPRESS_DEVICE_MANAGEMENT] = value::suppressDeviceManagement 184 intent[EXTRAS.EXTRA_CALLING_PACKAGE] = value::callingPackage 185 intent[EXTRAS.EXTRA_IS_USER_OWNER] = value::isMainUser 186 intent[EXTRAS.EXTRA_DM_STATUS] = value::dmStatus 187 intent[EXTRAS.EXTRA_IS_UNICORN_ACCOUNT] = value::isUnicornAccount 188 intent[EXTRAS.EXTRA_FLOW] = value::flow 189 intent[EXTRAS.EXTRA_OPTIONS] = value::options 190 intent[EXTRAS.EXTRA_UNMANAGED_WORK_PROFILE_MODE] = value::unmanagedWorkProfileMode 191 } 192 readnull193 override fun NodeAwareIntentScope.read(): EmmArguments = 194 object : EmmArguments { 195 override val suwArguments by read(suwArgumentsSerializer) 196 override val account by parcelable<Account>(EXTRAS.EXTRA_ACCOUNT).required 197 override val options by parcelable<Bundle>(EXTRAS.EXTRA_OPTIONS) or Bundle.EMPTY 198 override val flow by int(EXTRAS.EXTRA_FLOW) 199 override val dmStatus by string(EXTRAS.EXTRA_DM_STATUS) 200 override val isSetupWizard by boolean(EXTRAS.EXTRA_IS_SETUP_WIZARD) or false 201 override val suppressDeviceManagement by 202 boolean(EXTRAS.EXTRA_SUPPRESS_DEVICE_MANAGEMENT) or false 203 override val callingPackage by string(EXTRAS.EXTRA_CALLING_PACKAGE) or "" 204 override val isMainUser by boolean(EXTRAS.EXTRA_IS_USER_OWNER) or false 205 override val isUnicornAccount by boolean(EXTRAS.EXTRA_IS_UNICORN_ACCOUNT) or false 206 override val unmanagedWorkProfileMode by 207 int(EXTRAS.EXTRA_UNMANAGED_WORK_PROFILE_MODE) or UNMANAGED_WORK_PROFILE_MODE_UNSPECIFIED 208 } 209 } 210