1 /*
2  * Copyright (C) 2023 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  *      https://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 package com.android.packageinstaller.v2.model
17 
18 import android.app.Activity
19 import android.app.Notification
20 import android.content.Intent
21 import com.android.packageinstaller.R
22 
23 sealed class UninstallStage(val stageCode: Int) {
24 
25     companion object {
26         const val STAGE_DEFAULT = -1
27         const val STAGE_ABORTED = 0
28         const val STAGE_READY = 1
29         const val STAGE_USER_ACTION_REQUIRED = 2
30         const val STAGE_UNINSTALLING = 3
31         const val STAGE_SUCCESS = 4
32         const val STAGE_FAILED = 5
33     }
34 }
35 
36 class UninstallReady : UninstallStage(STAGE_READY)
37 
38 data class UninstallUserActionRequired(
39     val title: String? = null,
40     val message: String? = null,
41     val appDataSize: Long = 0
42 ) : UninstallStage(STAGE_USER_ACTION_REQUIRED)
43 
44 data class UninstallUninstalling(val appLabel: CharSequence, val isCloneUser: Boolean) :
45     UninstallStage(STAGE_UNINSTALLING)
46 
47 data class UninstallSuccess(
48     val resultIntent: Intent? = null,
49     val activityResultCode: Int = 0,
50     val message: String? = null,
51 ) : UninstallStage(STAGE_SUCCESS)
52 
53 data class UninstallFailed(
54     val returnResult: Boolean,
55     /**
56      * If the caller wants the result back, the intent will hold the uninstall failure status code
57      * and legacy code.
58      */
59     val resultIntent: Intent? = null,
60     val activityResultCode: Int = Activity.RESULT_CANCELED,
61     /**
62      * ID used to show [uninstallNotification]
63      */
64     val uninstallNotificationId: Int? = null,
65     /**
66      * When the user does not request a result back, this notification will be shown indicating the
67      * reason for uninstall failure.
68      */
69     val uninstallNotification: Notification? = null,
70 ) : UninstallStage(STAGE_FAILED) {
71 
72     init {
73         if (uninstallNotification != null && uninstallNotificationId == null) {
74             throw IllegalArgumentException(
75                 "uninstallNotification cannot be set without uninstallNotificationId"
76             )
77         }
78     }
79 }
80 
81 data class UninstallAborted(val abortReason: Int) : UninstallStage(STAGE_ABORTED) {
82 
83     var dialogTitleResource = 0
84     var dialogTextResource = 0
85     val activityResultCode = Activity.RESULT_FIRST_USER
86 
87     init {
88         when (abortReason) {
89             ABORT_REASON_APP_UNAVAILABLE -> {
90                 dialogTitleResource = R.string.app_not_found_dlg_title
91                 dialogTextResource = R.string.app_not_found_dlg_text
92             }
93 
94             ABORT_REASON_USER_NOT_ALLOWED -> {
95                 dialogTitleResource = 0
96                 dialogTextResource = R.string.user_is_not_allowed_dlg_text
97             }
98 
99             else -> {
100                 dialogTitleResource = 0
101                 dialogTextResource = R.string.generic_error_dlg_text
102             }
103         }
104     }
105 
106     companion object {
107         const val ABORT_REASON_GENERIC_ERROR = 0
108         const val ABORT_REASON_APP_UNAVAILABLE = 1
109         const val ABORT_REASON_USER_NOT_ALLOWED = 2
110     }
111 }
112 
113