1 /*
2  * Copyright (C) 2019 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.permissioncontroller.permission.ui.handheld
18 
19 import android.app.Application
20 import android.content.Context
21 import android.os.UserHandle
22 import android.text.TextUtils
23 import android.view.View
24 import android.widget.ImageView
25 import android.widget.TextView
26 import androidx.preference.AndroidResources
27 import androidx.preference.Preference
28 import androidx.preference.PreferenceViewHolder
29 import com.android.permissioncontroller.R
30 import com.android.permissioncontroller.permission.utils.KotlinUtils
31 
32 /**
33  * A Preference representing a package for a user, which loads and displays its icon only upon
34  * being bound to a viewHolder. This lets us synchronously load package icons and labels, while
35  * still displaying the PermissionAppsFragment instantly.
36  *
37  * @param app The current application
38  * @param packageName The name of the package whose icon this preference will retrieve
39  * @param user The user whose package icon will be retrieved
40  * @param context The current context
41  */
42 open class SmartIconLoadPackagePermissionPreference constructor(
43     private val app: Application,
44     private val packageName: String,
45     private val user: UserHandle,
46     context: Context
47 ) : Preference(context) {
48 
49     private var titleContentDescription: CharSequence? = null
50 
51     /**
52      * Loads the package's badged icon upon being bound to a viewholder. This allows us to load
53      * icons synchronously, because we only load the icons that are visible on the screen.
54      */
55     override fun onBindViewHolder(holder: PreferenceViewHolder) {
56         super.onBindViewHolder(holder)
57 
58         val title = holder.findViewById(android.R.id.title) as TextView
59         title.maxLines = 1
60         title.ellipsize = TextUtils.TruncateAt.END
61 
62         val imageView = holder.findViewById(android.R.id.icon) as ImageView
63 
64         imageView.maxWidth =
65             context.resources.getDimensionPixelSize(R.dimen.secondary_app_icon_size)
66         imageView.maxHeight =
67             context.resources.getDimensionPixelSize(R.dimen.secondary_app_icon_size)
68         imageView.setImageDrawable(KotlinUtils.getBadgedPackageIcon(app, packageName, user))
69         imageView.visibility = View.VISIBLE
70 
71         var imageFrame: View? = holder.findViewById(R.id.icon_frame)
72         if (imageFrame == null) {
73             imageFrame = holder.findViewById(AndroidResources.ANDROID_R_ICON_FRAME)
74         }
75         if (imageFrame != null) {
76             imageFrame.visibility = View.VISIBLE
77         }
78         holder.findViewById(android.R.id.title)?.let {
79             it.contentDescription = titleContentDescription
80         }
81     }
82 
83     fun setTitleContentDescription(contentDescription: CharSequence) {
84         titleContentDescription = contentDescription
85     }
86 }
87