blob: 75b8a056df1dde05aa5e1010d63ad1fe5dd56e40 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.android.systemui.privacy
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.ColorStateList
import android.os.UserHandle
import android.provider.Settings
import android.util.IconDrawableFactory
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.android.systemui.Dependency
import com.android.systemui.R
import com.android.systemui.plugins.ActivityStarter
import java.util.concurrent.TimeUnit
class OngoingPrivacyDialog constructor(
private val context: Context,
private val dialogBuilder: PrivacyDialogBuilder
) {
private val iconSize = context.resources.getDimensionPixelSize(
R.dimen.ongoing_appops_dialog_icon_size)
private val plusSize = context.resources.getDimensionPixelSize(
R.dimen.ongoing_appops_dialog_app_plus_size)
private val iconColor = context.resources.getColor(
com.android.internal.R.color.text_color_primary, context.theme)
private val plusColor: Int
private val iconMargin = context.resources.getDimensionPixelSize(
R.dimen.ongoing_appops_dialog_icon_margin)
private val MAX_ITEMS = context.resources.getInteger(R.integer.ongoing_appops_dialog_max_apps)
private val iconFactory = IconDrawableFactory.newInstance(context, true)
private var dismissDialog: (() -> Unit)? = null
private val appsAndTypes = dialogBuilder.appsAndTypes
.sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps
{ it.second.min() },
{ it.first }))
init {
val a = context.theme.obtainStyledAttributes(
intArrayOf(com.android.internal.R.attr.colorAccent))
plusColor = a.getColor(0, 0)
a.recycle()
}
fun createDialog(): Dialog {
val builder = AlertDialog.Builder(context).apply {
setPositiveButton(R.string.ongoing_privacy_dialog_ok, null)
setNeutralButton(R.string.ongoing_privacy_dialog_open_settings,
object : DialogInterface.OnClickListener {
val intent = Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra(
Intent.EXTRA_DURATION_MILLIS, TimeUnit.MINUTES.toMillis(1))
@Suppress("DEPRECATION")
override fun onClick(dialog: DialogInterface?, which: Int) {
Dependency.get(ActivityStarter::class.java)
.postStartActivityDismissingKeyguard(intent, 0)
}
})
}
builder.setView(getContentView())
val dialog = builder.create()
dismissDialog = dialog::dismiss
return dialog
}
fun getContentView(): View {
val layoutInflater = LayoutInflater.from(context)
val contentView = layoutInflater.inflate(R.layout.ongoing_privacy_dialog_content, null)
val title = contentView.findViewById(R.id.title) as TextView
val appsList = contentView.findViewById(R.id.items_container) as LinearLayout
title.setText(dialogBuilder.getDialogTitle())
val numItems = appsAndTypes.size
for (i in 0..(numItems - 1)) {
if (i >= MAX_ITEMS) break
val item = appsAndTypes[i]
addAppItem(appsList, item.first, item.second, dialogBuilder.types.size > 1)
}
if (numItems > MAX_ITEMS) {
val overflow = contentView.findViewById(R.id.overflow) as LinearLayout
overflow.visibility = View.VISIBLE
val overflowText = overflow.findViewById(R.id.app_name) as TextView
overflowText.text = context.resources.getQuantityString(
R.plurals.ongoing_privacy_dialog_overflow_text,
numItems - MAX_ITEMS,
numItems - MAX_ITEMS
)
val overflowPlus = overflow.findViewById(R.id.app_icon) as ImageView
val lp = overflowPlus.layoutParams.apply {
height = plusSize
width = plusSize
}
overflowPlus.layoutParams = lp
overflowPlus.apply {
val plus = context.getDrawable(R.drawable.plus)
imageTintList = ColorStateList.valueOf(plusColor)
setImageDrawable(plus)
}
}
return contentView
}
@Suppress("DEPRECATION")
private fun addAppItem(
itemList: LinearLayout,
app: PrivacyApplication,
types: List<PrivacyType>,
showIcons: Boolean = true
) {
val layoutInflater = LayoutInflater.from(context)
val item = layoutInflater.inflate(R.layout.ongoing_privacy_dialog_item, itemList, false)
val appIcon = item.findViewById(R.id.app_icon) as ImageView
val appName = item.findViewById(R.id.app_name) as TextView
val icons = item.findViewById(R.id.icons) as LinearLayout
val lp = LinearLayout.LayoutParams(iconSize, iconSize).apply {
gravity = Gravity.CENTER_VERTICAL
marginStart = iconMargin
}
app.icon.let {
appIcon.setImageDrawable(iconFactory.getShadowedIcon(it))
}
appName.text = app.applicationName
if (showIcons) {
dialogBuilder.generateIconsForApp(types).forEachIndexed { index, it ->
it.setBounds(0, 0, iconSize, iconSize)
val image = ImageView(context).apply {
imageTintList = ColorStateList.valueOf(iconColor)
setImageDrawable(it)
}
image.contentDescription = types[index].getName(context)
icons.addView(image, lp)
}
icons.visibility = View.VISIBLE
} else {
icons.visibility = View.GONE
}
try {
// Check if package exists
context.packageManager.getPackageInfo(app.packageName, 0)
item.setOnClickListener(object : View.OnClickListener {
val intent = Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS)
.putExtra(Intent.EXTRA_PACKAGE_NAME, app.packageName)
.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(app.uid))
override fun onClick(v: View?) {
Dependency.get(ActivityStarter::class.java)
.postStartActivityDismissingKeyguard(intent, 0)
dismissDialog?.invoke()
}
})
} catch (e: PackageManager.NameNotFoundException) {}
itemList.addView(item)
}
}