• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.deviceinfo.firmwareversion
18 
19 import android.content.Context
20 import android.content.Intent
21 import android.content.pm.PackageManager
22 import android.text.format.DateFormat
23 import android.util.Log
24 import androidx.preference.Preference
25 import com.android.settings.R
26 import com.android.settings.flags.Flags
27 import com.android.settings.utils.getLocale
28 import com.android.settingslib.metadata.PreferenceAvailabilityProvider
29 import com.android.settingslib.metadata.PreferenceMetadata
30 import com.android.settingslib.metadata.PreferenceSummaryProvider
31 import com.android.settingslib.preference.PreferenceBinding
32 import java.text.ParseException
33 import java.text.SimpleDateFormat
34 import java.util.Date
35 import java.util.TimeZone
36 
37 // LINT.IfChange
38 class MainlineModuleVersionPreference :
39     PreferenceMetadata,
40     PreferenceSummaryProvider,
41     PreferenceAvailabilityProvider,
42     PreferenceBinding {
43 
44     private var moduleVersion: String? = null
45 
46     override val key: String
47         get() = "module_version"
48 
49     override val title: Int
50         get() = R.string.module_version
51 
getSummarynull52     override fun getSummary(context: Context): CharSequence? {
53         val version = getModuleVersion(context)
54         if (version.isEmpty()) return null
55 
56         val locale = context.getLocale()
57         fun parseDate(pattern: String): Date? {
58             val simpleDateFormat = SimpleDateFormat(pattern, locale)
59             simpleDateFormat.timeZone = TimeZone.getDefault()
60             return try {
61                 simpleDateFormat.parse(version)
62             } catch (e: ParseException) {
63                 null
64             }
65         }
66 
67         val date = parseDate("yyyy-MM-dd") ?: parseDate("yyyy-MM")
68         return if (date == null) {
69             Log.w(TAG, "Cannot parse mainline versionName ($version) as date")
70             version
71         } else {
72             DateFormat.format(DateFormat.getBestDateTimePattern(locale, "dMMMMyyyy"), date)
73         }
74     }
75 
intentnull76     override fun intent(context: Context): Intent? {
77         val packageManager = context.packageManager
78         val intentPackage =
79             if (Flags.mainlineModuleExplicitIntent()) {
80                 context.getString(R.string.config_mainline_module_update_package)
81             } else {
82                 null
83             }
84         fun String.resolveIntent() =
85             Intent(this).let {
86                 if (intentPackage != null) it.setPackage(intentPackage)
87                 if (packageManager.resolveActivity(it, 0) != null) it else null
88             }
89 
90         return MODULE_UPDATE_ACTION_V2.resolveIntent() ?: MODULE_UPDATE_ACTION.resolveIntent()
91     }
92 
isAvailablenull93     override fun isAvailable(context: Context) = getModuleVersion(context).isNotEmpty()
94 
95     override fun bind(preference: Preference, metadata: PreferenceMetadata) {
96         super.bind(preference, metadata)
97         // This seems unnecessary, just follow existing behavior to pass test
98         if (preference.intent == null) preference.setSummary(R.string.summary_placeholder)
99         preference.isCopyingEnabled = true
100     }
101 
getModuleVersionnull102     private fun getModuleVersion(context: Context): String =
103         moduleVersion ?: context.getVersion().also { moduleVersion = it }
104 
Contextnull105     private fun Context.getVersion(): String {
106         val moduleProvider =
107             getString(com.android.internal.R.string.config_defaultModuleMetadataProvider)
108         if (moduleProvider.isEmpty()) return ""
109         return try {
110             packageManager.getPackageInfo(moduleProvider, 0)?.versionName ?: ""
111         } catch (e: PackageManager.NameNotFoundException) {
112             Log.e(TAG, "Failed to get mainline version.", e)
113             ""
114         }
115     }
116 
117     companion object {
118         private const val TAG = "MainlineModulePreference"
119         const val MODULE_UPDATE_ACTION = "android.settings.MODULE_UPDATE_SETTINGS"
120         const val MODULE_UPDATE_ACTION_V2 = "android.settings.MODULE_UPDATE_VERSIONS"
121     }
122 }
123 // LINT.ThenChange(MainlineModuleVersionPreferenceController.java)
124