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  *      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.settings.system
18 
19 import android.content.Context
20 import android.os.Build
21 import android.os.SystemUpdateManager
22 import android.os.UserManager
23 import android.util.Log
24 import androidx.lifecycle.Lifecycle
25 import androidx.lifecycle.LifecycleOwner
26 import androidx.lifecycle.lifecycleScope
27 import androidx.lifecycle.repeatOnLifecycle
28 import androidx.preference.Preference
29 import androidx.preference.PreferenceScreen
30 import com.android.settings.R
31 import com.android.settings.core.BasePreferenceController
32 import com.android.settingslib.spaprivileged.framework.common.userManager
33 import kotlinx.coroutines.launch
34 
35 open class SystemUpdatePreferenceController(context: Context, preferenceKey: String) :
36     BasePreferenceController(context, preferenceKey) {
37     private val userManager: UserManager = context.userManager
38     private val systemUpdateRepository = SystemUpdateRepository(context)
39     private val clientInitiatedActionRepository = ClientInitiatedActionRepository(context)
40     private lateinit var preference: Preference
41 
getAvailabilityStatusnull42     override fun getAvailabilityStatus() =
43         if (mContext.resources.getBoolean(R.bool.config_show_system_update_settings) &&
44             userManager.isAdminUser
45         ) AVAILABLE else UNSUPPORTED_ON_DEVICE
46 
47     override fun displayPreference(screen: PreferenceScreen) {
48         super.displayPreference(screen)
49         preference = screen.findPreference(preferenceKey)!!
50         if (isAvailable) {
51             val intent = systemUpdateRepository.getSystemUpdateIntent()
52             if (intent != null) {  // Replace the intent with this specific activity
53                 preference.intent = intent
54             } else { // Did not find a matching activity, so remove the preference
55                 screen.removePreference(preference)
56             }
57         }
58     }
59 
handlePreferenceTreeClicknull60     override fun handlePreferenceTreeClick(preference: Preference): Boolean {
61         if (preferenceKey == preference.key) {
62             clientInitiatedActionRepository.onSystemUpdate()
63         }
64         // always return false here because this handler does not want to block other handlers.
65         return false
66     }
67 
onViewCreatednull68     override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
69         viewLifecycleOwner.lifecycleScope.launch {
70             viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
71                 preference.summary = calculateSummary()
72             }
73         }
74     }
75 
calculateSummarynull76     private suspend fun calculateSummary(): String {
77         val updateInfo = mContext.getSystemUpdateInfo() ?: return getReleaseVersionSummary()
78 
79         val status = updateInfo.getInt(SystemUpdateManager.KEY_STATUS)
80         if (status == SystemUpdateManager.STATUS_UNKNOWN) {
81             Log.d(TAG, "Update statue unknown")
82         }
83         when (status) {
84             SystemUpdateManager.STATUS_WAITING_DOWNLOAD,
85             SystemUpdateManager.STATUS_IN_PROGRESS,
86             SystemUpdateManager.STATUS_WAITING_INSTALL,
87             SystemUpdateManager.STATUS_WAITING_REBOOT -> {
88                 return mContext.getString(R.string.android_version_pending_update_summary)
89             }
90 
91             SystemUpdateManager.STATUS_IDLE,
92             SystemUpdateManager.STATUS_UNKNOWN -> {
93                 val version = updateInfo.getString(SystemUpdateManager.KEY_TITLE)
94                 if (!version.isNullOrEmpty()) {
95                     return mContext.getString(R.string.android_version_summary, version)
96                 }
97             }
98         }
99         return getReleaseVersionSummary()
100     }
101 
getReleaseVersionSummarynull102     private fun getReleaseVersionSummary(): String = mContext.getString(
103         R.string.android_version_summary,
104         Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY,
105     )
106 
107     companion object {
108         private const val TAG = "SysUpdatePrefContr"
109     }
110 }
111