diff --git a/api/system-current.txt b/api/system-current.txt index 3e4ccb5372352..0a2463267c791 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1430,8 +1430,9 @@ package android.content { field public static final String ACTION_RESOLVE_INSTANT_APP_PACKAGE = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE"; field @RequiresPermission(android.Manifest.permission.REVIEW_ACCESSIBILITY_SERVICES) public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES = "android.intent.action.REVIEW_ACCESSIBILITY_SERVICES"; field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_APP_PERMISSION_USAGE = "android.intent.action.REVIEW_APP_PERMISSION_USAGE"; + field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_ONGOING_PERMISSION_USAGE = "android.intent.action.REVIEW_ONGOING_PERMISSION_USAGE"; field public static final String ACTION_REVIEW_PERMISSIONS = "android.intent.action.REVIEW_PERMISSIONS"; - field public static final String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE"; + field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE"; field public static final String ACTION_ROLLBACK_COMMITTED = "android.intent.action.ROLLBACK_COMMITTED"; field public static final String ACTION_SHOW_SUSPENDED_APP_DETAILS = "android.intent.action.SHOW_SUSPENDED_APP_DETAILS"; field @Deprecated public static final String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED"; diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index d331c0f026f6a..1735b05148fa3 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -3422,7 +3422,6 @@ message HiddenApiUsed { * - When user clicks privacy chip * - How does the user exit the Privacy Dialog * Logged from: - * packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt * packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java */ message PrivacyIndicatorsInteracted { diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 93a9daced987d..6bb9498043905 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2078,6 +2078,9 @@ public class Intent implements Parcelable, Cloneable { *

* Output: Nothing. *

+ *

+ * This requires {@link android.Manifest.permission#GRANT_RUNTIME_PERMISSIONS} permission. + *

* * @see #EXTRA_PERMISSION_NAME * @see #EXTRA_PERMISSION_GROUP_NAME @@ -2086,10 +2089,34 @@ public class Intent implements Parcelable, Cloneable { * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE"; + /** + * Activity action: Launch UI to review ongoing app uses of permissions. + *

+ * Input: {@link #EXTRA_DURATION_MILLIS} specifies the minimum number of milliseconds of recent + * activity to show (optional). Must be non-negative. + *

+ *

+ * Output: Nothing. + *

+ *

+ * This requires {@link android.Manifest.permission#GRANT_RUNTIME_PERMISSIONS} permission. + *

+ * + * @see #EXTRA_DURATION_MILLIS + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_REVIEW_ONGOING_PERMISSION_USAGE = + "android.intent.action.REVIEW_ONGOING_PERMISSION_USAGE"; + /** * Activity action: Launch UI to review uses of permissions for a single app. *

diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt deleted file mode 100644 index cf170187cdaa9..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.util.StatsLog -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 iconColor = context.resources.getColor( - com.android.internal.R.color.text_color_primary, context.theme) - private val iconMargin = context.resources.getDimensionPixelSize( - R.dimen.ongoing_appops_dialog_icon_margin) - 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 })) - - fun createDialog(): Dialog { - val builder = AlertDialog.Builder(context).apply { - setPositiveButton(R.string.ongoing_privacy_dialog_ok, - object : DialogInterface.OnClickListener { - override fun onClick(dialog: DialogInterface?, which: Int) { - StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED, - StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__DIALOG_DISMISS) - } - }) - 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) { - StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED, StatsLog - .PRIVACY_INDICATORS_INTERACTED__TYPE__DIALOG_PRIVACY_SETTINGS) - 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)) { - val item = appsAndTypes[i] - addAppItem(appsList, item.first, item.second, dialogBuilder.types.size > 1) - } - return contentView - } - - @Suppress("DEPRECATION") - private fun addAppItem( - itemList: LinearLayout, - app: PrivacyApplication, - types: List, - 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?) { - StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED, - StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__DIALOG_LINE_ITEM, - app.packageName) - Dependency.get(ActivityStarter::class.java) - .postStartActivityDismissingKeyguard(intent, 0) - dismissDialog?.invoke() - } - }) - } catch (e: PackageManager.NameNotFoundException) {} - - itemList.addView(item) - } -} diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 4862b9eddc851..c897b9c3b4671 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -23,7 +23,6 @@ import android.animation.AnimatorListenerAdapter; import android.annotation.ColorInt; import android.app.ActivityManager; import android.app.AlarmManager; -import android.app.Dialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -62,7 +61,6 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.privacy.OngoingPrivacyChip; -import com.android.systemui.privacy.OngoingPrivacyDialog; import com.android.systemui.privacy.PrivacyDialogBuilder; import com.android.systemui.privacy.PrivacyItem; import com.android.systemui.privacy.PrivacyItemController; @@ -71,7 +69,6 @@ import com.android.systemui.statusbar.phone.PhoneStatusBarView; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager; import com.android.systemui.statusbar.phone.StatusIconContainer; -import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.Clock; import com.android.systemui.statusbar.policy.DateView; import com.android.systemui.statusbar.policy.NextAlarmController; @@ -561,11 +558,8 @@ public class QuickStatusBarHeader extends RelativeLayout implements StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED, StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_CLICKED); mUiHandler.post(() -> { - Dialog mDialog = new OngoingPrivacyDialog(mContext, builder).createDialog(); - SystemUIDialog.setShowForAllUsers(mDialog, false); - SystemUIDialog.registerDismissListener(mDialog); - SystemUIDialog.setWindowOnTop(mDialog); - mActivityStarter.postQSRunnableDismissingKeyguard(() -> mDialog.show()); + mActivityStarter.postStartActivityDismissingKeyguard( + new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0); mHost.collapsePanels(); }); }