Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2018 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file |
| 5 | * except in compliance with the License. You may obtain a copy of the License at |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software distributed under the |
| 10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 11 | * KIND, either express or implied. See the License for the specific language governing |
| 12 | * permissions and limitations under the License. |
| 13 | */ |
| 14 | |
| 15 | package com.android.systemui.privacy |
| 16 | |
| 17 | import android.app.AlertDialog |
| 18 | import android.app.Dialog |
| 19 | import android.content.Context |
| 20 | import android.content.DialogInterface |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 21 | import android.content.Intent |
| 22 | import android.content.res.ColorStateList |
Fabian Kozynski | bb68be0 | 2018-11-19 12:58:01 -0500 | [diff] [blame] | 23 | import android.view.Gravity |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 24 | import android.view.LayoutInflater |
| 25 | import android.view.View |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 26 | import android.widget.ImageView |
| 27 | import android.widget.LinearLayout |
| 28 | import android.widget.TextView |
| 29 | import com.android.systemui.Dependency |
| 30 | import com.android.systemui.R |
| 31 | import com.android.systemui.plugins.ActivityStarter |
| 32 | |
| 33 | class OngoingPrivacyDialog constructor( |
| 34 | val context: Context, |
| 35 | val dialogBuilder: PrivacyDialogBuilder |
| 36 | ) { |
| 37 | |
Fabian Kozynski | bb68be0 | 2018-11-19 12:58:01 -0500 | [diff] [blame] | 38 | private val iconSize = context.resources.getDimensionPixelSize( |
| 39 | R.dimen.ongoing_appops_dialog_icon_size) |
| 40 | private val iconColor = context.resources.getColor( |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 41 | com.android.internal.R.color.text_color_primary, context.theme) |
Fabian Kozynski | bb68be0 | 2018-11-19 12:58:01 -0500 | [diff] [blame] | 42 | private val iconMargin = context.resources.getDimensionPixelSize( |
| 43 | R.dimen.ongoing_appops_dialog_icon_margin) |
| 44 | private val MAX_ITEMS = context.resources.getInteger(R.integer.ongoing_appops_dialog_max_apps) |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 45 | |
| 46 | fun createDialog(): Dialog { |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 47 | val builder = AlertDialog.Builder(context).apply { |
| 48 | setNegativeButton(R.string.ongoing_privacy_dialog_cancel, null) |
| 49 | setPositiveButton(R.string.ongoing_privacy_dialog_open_settings, |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 50 | object : DialogInterface.OnClickListener { |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 51 | val intent = Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE) |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 52 | |
| 53 | override fun onClick(dialog: DialogInterface?, which: Int) { |
| 54 | Dependency.get(ActivityStarter::class.java).startActivity(intent, false) |
| 55 | } |
| 56 | }) |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 57 | } |
| 58 | builder.setView(getContentView()) |
| 59 | return builder.create() |
| 60 | } |
| 61 | |
| 62 | fun getContentView(): View { |
| 63 | val layoutInflater = LayoutInflater.from(context) |
| 64 | val contentView = layoutInflater.inflate(R.layout.ongoing_privacy_dialog_content, null) |
| 65 | |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 66 | val title = contentView.findViewById(R.id.title) as TextView |
| 67 | val appsList = contentView.findViewById(R.id.items_container) as LinearLayout |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 68 | |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 69 | title.setText(dialogBuilder.getDialogTitle()) |
| 70 | |
| 71 | val numItems = dialogBuilder.appsAndTypes.size |
| 72 | for (i in 0..(numItems - 1)) { |
| 73 | if (i >= MAX_ITEMS) break |
| 74 | val item = dialogBuilder.appsAndTypes[i] |
| 75 | addAppItem(appsList, item.first, item.second, dialogBuilder.types.size > 1) |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 76 | } |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 77 | |
| 78 | if (numItems > MAX_ITEMS) { |
| 79 | val overflow = contentView.findViewById(R.id.overflow) as LinearLayout |
| 80 | overflow.visibility = View.VISIBLE |
| 81 | val overflowText = overflow.findViewById(R.id.app_name) as TextView |
| 82 | overflowText.text = context.resources.getQuantityString( |
| 83 | R.plurals.ongoing_privacy_dialog_overflow_text, |
| 84 | numItems - MAX_ITEMS, |
| 85 | numItems - MAX_ITEMS |
| 86 | ) |
| 87 | val overflowPlus = overflow.findViewById(R.id.app_icon) as ImageView |
| 88 | overflowPlus.apply { |
| 89 | imageTintList = ColorStateList.valueOf(iconColor) |
| 90 | setImageDrawable(context.getDrawable(R.drawable.plus)) |
| 91 | } |
| 92 | } |
| 93 | |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 94 | return contentView |
| 95 | } |
| 96 | |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 97 | private fun addAppItem( |
| 98 | itemList: LinearLayout, |
| 99 | app: PrivacyApplication, |
| 100 | types: List<PrivacyType>, |
| 101 | showIcons: Boolean = true |
| 102 | ) { |
| 103 | val layoutInflater = LayoutInflater.from(context) |
| 104 | val item = layoutInflater.inflate(R.layout.ongoing_privacy_dialog_item, itemList, false) |
| 105 | val appIcon = item.findViewById(R.id.app_icon) as ImageView |
| 106 | val appName = item.findViewById(R.id.app_name) as TextView |
| 107 | val icons = item.findViewById(R.id.icons) as LinearLayout |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 108 | |
Fabian Kozynski | 508422b | 2018-12-20 10:58:17 -0500 | [diff] [blame^] | 109 | val lp = LinearLayout.LayoutParams(iconSize, iconSize).apply { |
Fabian Kozynski | bb68be0 | 2018-11-19 12:58:01 -0500 | [diff] [blame] | 110 | gravity = Gravity.CENTER_VERTICAL |
| 111 | marginStart = iconMargin |
| 112 | } |
| 113 | |
Fabian Kozynski | 508422b | 2018-12-20 10:58:17 -0500 | [diff] [blame^] | 114 | app.icon.let { |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 115 | appIcon.setImageDrawable(it) |
| 116 | } |
| 117 | |
| 118 | appName.text = app.applicationName |
| 119 | if (showIcons) { |
| 120 | dialogBuilder.generateIconsForApp(types).forEach { |
| 121 | it.setBounds(0, 0, iconSize, iconSize) |
| 122 | val image = ImageView(context).apply { |
| 123 | imageTintList = ColorStateList.valueOf(iconColor) |
| 124 | setImageDrawable(it) |
| 125 | } |
Fabian Kozynski | bb68be0 | 2018-11-19 12:58:01 -0500 | [diff] [blame] | 126 | icons.addView(image, lp) |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 127 | } |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 128 | icons.visibility = View.VISIBLE |
| 129 | } else { |
| 130 | icons.visibility = View.GONE |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 131 | } |
Fabian Kozynski | ef12449 | 2018-11-02 11:02:11 -0400 | [diff] [blame] | 132 | itemList.addView(item) |
Fabian Kozynski | 1263824 | 2018-10-12 15:33:41 -0400 | [diff] [blame] | 133 | } |
| 134 | } |