diff options
| author | 2019-05-31 22:43:08 +0000 | |
|---|---|---|
| committer | 2019-05-31 22:43:08 +0000 | |
| commit | aa4545194b0e48c34649229e2af3e7a0e81ba3a4 (patch) | |
| tree | 725a218c93980e7f29ff2ba98879856601c08f9e | |
| parent | d28f0c8c78a8aac37ae7e66d4a737f8ed45aecf7 (diff) | |
| parent | 9a560e068d953d44472f0592a91357dd70ae7a3b (diff) | |
Merge "DO NOT MERGE Remove Privacy Indicators" into qt-dev
16 files changed, 9 insertions, 1305 deletions
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java index 1b0a458b3fbc..48ca766f0da2 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java @@ -106,13 +106,6 @@ public final class SystemUiDeviceConfigFlags { */ public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days"; - // Flag related to Privacy Indicators - - /** - * Whether the Permissions Hub is showing. - */ - public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled"; - // Flags related to Assistant Handles /** diff --git a/packages/SystemUI/res/drawable/privacy_chip_bg.xml b/packages/SystemUI/res/drawable/privacy_chip_bg.xml deleted file mode 100644 index b7b21fa53b62..000000000000 --- a/packages/SystemUI/res/drawable/privacy_chip_bg.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - 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. ---> - -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <solid android:color="#242424" /> <!-- 14% of white --> - <padding android:paddingTop="@dimen/ongoing_appops_chip_bg_padding" - android:paddingBottom="@dimen/ongoing_appops_chip_bg_padding" /> - <corners android:radius="@dimen/ongoing_appops_chip_bg_corner_radius" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml deleted file mode 100644 index dce9ce16e9cd..000000000000 --- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - 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. ---> - - -<com.android.systemui.privacy.OngoingPrivacyChip - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/privacy_chip" - android:layout_height="match_parent" - android:layout_width="wrap_content" - android:layout_gravity="center_vertical|end" - android:gravity="center_vertical" - android:orientation="horizontal" - android:focusable="true" > - - <FrameLayout - android:id="@+id/background" - android:layout_height="@dimen/ongoing_appops_chip_height" - android:minWidth="48dp" - android:layout_width="wrap_content" > - <LinearLayout - android:id="@+id/icons_container" - android:layout_height="match_parent" - android:layout_width="wrap_content" - android:gravity="center_vertical" - /> - </FrameLayout> -</com.android.systemui.privacy.OngoingPrivacyChip>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml b/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml deleted file mode 100644 index 5595b130e041..000000000000 --- a/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - 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. ---> - -<TextView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textDirection="locale" - android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary" -/>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml index cd9f780ca249..54fb2168dfa9 100644 --- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml +++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml @@ -22,19 +22,11 @@ android:layout_height="@*android:dimen/quick_qs_offset_height" android:clipChildren="false" android:clipToPadding="false" - android:gravity="center" android:orientation="horizontal" android:clickable="true" android:paddingStart="@dimen/status_bar_padding_start" android:paddingEnd="@dimen/status_bar_padding_end" > - <LinearLayout - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:orientation="horizontal" - android:gravity="center_vertical|start" > - <com.android.systemui.statusbar.policy.Clock android:id="@+id/clock" android:layout_width="wrap_content" @@ -46,23 +38,4 @@ android:singleLine="true" android:textAppearance="@style/TextAppearance.StatusBar.Clock" systemui:showDark="false" /> - </LinearLayout> - - <android.widget.Space - android:id="@+id/space" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_gravity="center_vertical|center_horizontal" - android:visibility="gone" /> - - <LinearLayout - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:orientation="horizontal" - android:gravity="center_vertical|end" > - - <include layout="@layout/ongoing_privacy_chip" /> - - </LinearLayout> </LinearLayout> diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 7a82402fda13..9f4a4e08bbfd 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -48,7 +48,6 @@ import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.PowerUI; -import com.android.systemui.privacy.PrivacyItemController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -287,7 +286,6 @@ public class Dependency extends SystemUI { @Inject Lazy<SensorPrivacyManager> mSensorPrivacyManager; @Inject Lazy<AutoHideController> mAutoHideController; @Inject Lazy<ForegroundServiceNotificationListener> mForegroundServiceNotificationListener; - @Inject Lazy<PrivacyItemController> mPrivacyItemController; @Inject @Named(BG_LOOPER_NAME) Lazy<Looper> mBgLooper; @Inject @Named(BG_HANDLER_NAME) Lazy<Handler> mBgHandler; @Inject @Named(MAIN_HANDLER_NAME) Lazy<Handler> mMainHandler; @@ -472,7 +470,6 @@ public class Dependency extends SystemUI { mProviders.put(ForegroundServiceNotificationListener.class, mForegroundServiceNotificationListener::get); mProviders.put(ClockManager.class, mClockManager::get); - mProviders.put(PrivacyItemController.class, mPrivacyItemController::get); mProviders.put(ActivityManagerWrapper.class, mActivityManagerWrapper::get); mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get); mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get); diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index 49bd5bd09220..afb8e7421412 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -20,7 +20,6 @@ import static com.android.systemui.Dependency.BG_LOOPER_NAME; import android.app.AppOpsManager; import android.content.Context; -import android.content.pm.PackageManager; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; @@ -211,59 +210,6 @@ public class AppOpsControllerImpl implements AppOpsController, } /** - * Does the app-op code refer to a user sensitive permission for the specified user id - * and package. Only user sensitive permission should be shown to the user by default. - * - * @param appOpCode The code of the app-op. - * @param uid The uid of the user. - * @param packageName The name of the package. - * - * @return {@code true} iff the app-op item is user sensitive - */ - private boolean isUserSensitive(int appOpCode, int uid, String packageName) { - String permission = AppOpsManager.opToPermission(appOpCode); - if (permission == null) { - return false; - } - int permFlags = mContext.getPackageManager().getPermissionFlags(permission, - packageName, UserHandle.getUserHandleForUid(uid)); - return (permFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0; - } - - /** - * Does the app-op item refer to an operation that should be shown to the user. - * Only specficic ops (like SYSTEM_ALERT_WINDOW) or ops that refer to user sensitive - * permission should be shown to the user by default. - * - * @param item The item - * - * @return {@code true} iff the app-op item should be shown to the user - */ - private boolean isUserVisible(AppOpItem item) { - return isUserVisible(item.getCode(), item.getUid(), item.getPackageName()); - } - - - /** - * Does the app-op, uid and package name, refer to an operation that should be shown to the - * user. Only specficic ops (like {@link AppOpsManager.OP_SYSTEM_ALERT_WINDOW}) or - * ops that refer to user sensitive permission should be shown to the user by default. - * - * @param item The item - * - * @return {@code true} iff the app-op for should be shown to the user - */ - private boolean isUserVisible(int appOpCode, int uid, String packageName) { - // currently OP_SYSTEM_ALERT_WINDOW does not correspond to a platform permission - // which may be user senstive, so for now always show it to the user. - if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW) { - return true; - } - - return isUserSensitive(appOpCode, uid, packageName); - } - - /** * Returns a copy of the list containing all the active AppOps that the controller tracks. * * @return List of active AppOps information @@ -286,8 +232,8 @@ public class AppOpsControllerImpl implements AppOpsController, final int numActiveItems = mActiveItems.size(); for (int i = 0; i < numActiveItems; i++) { AppOpItem item = mActiveItems.get(i); - if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId) - && isUserVisible(item)) { + if ((userId == UserHandle.USER_ALL + || UserHandle.getUserId(item.getUid()) == userId)) { list.add(item); } } @@ -296,8 +242,8 @@ public class AppOpsControllerImpl implements AppOpsController, final int numNotedItems = mNotedItems.size(); for (int i = 0; i < numNotedItems; i++) { AppOpItem item = mNotedItems.get(i); - if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId) - && isUserVisible(item)) { + if ((userId == UserHandle.USER_ALL + || UserHandle.getUserId(item.getUid()) == userId)) { list.add(item); } } @@ -323,8 +269,7 @@ public class AppOpsControllerImpl implements AppOpsController, } private void notifySuscribers(int code, int uid, String packageName, boolean active) { - if (mCallbacksByCode.containsKey(code) - && isUserVisible(code, uid, packageName)) { + if (mCallbacksByCode.containsKey(code)) { for (Callback cb: mCallbacksByCode.get(code)) { cb.onActiveStateChanged(code, uid, packageName, active); } diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt deleted file mode 100644 index a5a915b88cad..000000000000 --- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt +++ /dev/null @@ -1,110 +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.content.Context -import android.util.AttributeSet -import android.view.Gravity -import android.view.ViewGroup -import android.widget.FrameLayout -import android.widget.ImageView -import android.widget.LinearLayout -import com.android.systemui.R - -class OngoingPrivacyChip @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttrs: Int = 0, - defStyleRes: Int = 0 -) : LinearLayout(context, attrs, defStyleAttrs, defStyleRes) { - - private val iconMarginExpanded = context.resources.getDimensionPixelSize( - R.dimen.ongoing_appops_chip_icon_margin_expanded) - private val iconMarginCollapsed = context.resources.getDimensionPixelSize( - R.dimen.ongoing_appops_chip_icon_margin_collapsed) - private val iconSize = - context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_size) - private val iconColor = context.resources.getColor( - R.color.status_bar_clock_color, context.theme) - private val sidePadding = - context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding) - private val backgroundDrawable = context.getDrawable(R.drawable.privacy_chip_bg) - private lateinit var iconsContainer: LinearLayout - private lateinit var back: FrameLayout - var expanded = false - set(value) { - if (value != field) { - field = value - updateView() - } - } - - var builder = PrivacyDialogBuilder(context, emptyList<PrivacyItem>()) - var privacyList = emptyList<PrivacyItem>() - set(value) { - field = value - builder = PrivacyDialogBuilder(context, value) - updateView() - } - - override fun onFinishInflate() { - super.onFinishInflate() - - back = findViewById(R.id.background) - iconsContainer = findViewById(R.id.icons_container) - } - - // Should only be called if the builder icons or app changed - private fun updateView() { - back.background = if (expanded) backgroundDrawable else null - val padding = if (expanded) sidePadding else 0 - back.setPaddingRelative(padding, 0, padding, 0) - fun setIcons(dialogBuilder: PrivacyDialogBuilder, iconsContainer: ViewGroup) { - iconsContainer.removeAllViews() - dialogBuilder.generateIcons().forEachIndexed { i, it -> - it.mutate() - it.setTint(iconColor) - val image = ImageView(context).apply { - setImageDrawable(it) - scaleType = ImageView.ScaleType.CENTER_INSIDE - } - iconsContainer.addView(image, iconSize, iconSize) - if (i != 0) { - val lp = image.layoutParams as MarginLayoutParams - lp.marginStart = if (expanded) iconMarginExpanded else iconMarginCollapsed - image.layoutParams = lp - } - } - } - - if (!privacyList.isEmpty()) { - generateContentDescription() - setIcons(builder, iconsContainer) - val lp = iconsContainer.layoutParams as FrameLayout.LayoutParams - lp.gravity = Gravity.CENTER_VERTICAL or - (if (expanded) Gravity.CENTER_HORIZONTAL else Gravity.END) - iconsContainer.layoutParams = lp - } else { - iconsContainer.removeAllViews() - } - requestLayout() - } - - private fun generateContentDescription() { - val typesText = builder.joinTypes() - contentDescription = context.getString( - R.string.ongoing_privacy_chip_content_multiple_apps, typesText) - } -}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt deleted file mode 100644 index d08a3733703b..000000000000 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt +++ /dev/null @@ -1,56 +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.content.Context -import android.graphics.drawable.Drawable -import com.android.systemui.R - -class PrivacyDialogBuilder(private val context: Context, itemsList: List<PrivacyItem>) { - - val appsAndTypes: List<Pair<PrivacyApplication, List<PrivacyType>>> - val types: List<PrivacyType> - private val separator = context.getString(R.string.ongoing_privacy_dialog_separator) - private val lastSeparator = context.getString(R.string.ongoing_privacy_dialog_last_separator) - - init { - appsAndTypes = itemsList.groupBy({ it.application }, { it.privacyType }) - .toList() - .sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps - { it.second.min() })) // Sort by "smallest" AppOpp (Location is largest) - types = itemsList.map { it.privacyType }.distinct().sorted() - } - - fun generateIconsForApp(types: List<PrivacyType>): List<Drawable> { - return types.sorted().map { it.getIcon(context) } - } - - fun generateIcons() = types.map { it.getIcon(context) } - - private fun <T> List<T>.joinWithAnd(): StringBuilder { - return subList(0, size - 1).joinTo(StringBuilder(), separator = separator).apply { - append(lastSeparator) - append(this@joinWithAnd.last()) - } - } - - fun joinTypes(): String { - return when (types.size) { - 0 -> "" - 1 -> types[0].getName(context) - else -> types.map { it.getName(context) }.joinWithAnd().toString() - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt deleted file mode 100644 index 290942412eed..000000000000 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt +++ /dev/null @@ -1,80 +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.content.Context -import android.content.pm.ApplicationInfo -import android.content.pm.PackageManager -import android.graphics.drawable.Drawable -import android.os.UserHandle -import android.util.IconDrawableFactory -import com.android.systemui.R - -typealias Privacy = PrivacyType - -enum class PrivacyType(private val nameId: Int, val iconId: Int) { - // This is uses the icons used by the corresponding permission groups in the AndroidManifest - TYPE_CAMERA(R.string.privacy_type_camera, - com.android.internal.R.drawable.perm_group_camera), - TYPE_MICROPHONE(R.string.privacy_type_microphone, - com.android.internal.R.drawable.perm_group_microphone), - TYPE_LOCATION(R.string.privacy_type_location, - com.android.internal.R.drawable.perm_group_location); - - fun getName(context: Context) = context.resources.getString(nameId) - - fun getIcon(context: Context) = context.resources.getDrawable(iconId, context.theme) -} - -data class PrivacyItem( - val privacyType: PrivacyType, - val application: PrivacyApplication -) - -data class PrivacyApplication(val packageName: String, val uid: Int, val context: Context) - : Comparable<PrivacyApplication> { - - override fun compareTo(other: PrivacyApplication): Int { - return applicationName.compareTo(other.applicationName) - } - - private val applicationInfo: ApplicationInfo? by lazy { - try { - val userHandle = UserHandle.getUserHandleForUid(uid) - context.createPackageContextAsUser(packageName, 0, userHandle).getPackageManager() - .getApplicationInfo(packageName, 0) - } catch (_: PackageManager.NameNotFoundException) { - null - } - } - val icon: Drawable by lazy { - applicationInfo?.let { - try { - val iconFactory = IconDrawableFactory.newInstance(context, true) - iconFactory.getBadgedIcon(it, UserHandle.getUserId(uid)) - } catch (_: Exception) { - null - } - } ?: context.getDrawable(android.R.drawable.sym_def_app_icon) - } - - val applicationName: String by lazy { - applicationInfo?.let { - context.packageManager.getApplicationLabel(it) as String - } ?: packageName - } - - override fun toString() = "PrivacyApplication(packageName=$packageName, uid=$uid)" -} diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt deleted file mode 100644 index 82a2c1fb43fb..000000000000 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +++ /dev/null @@ -1,294 +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.ActivityManager -import android.app.AppOpsManager -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import android.os.Handler -import android.os.Looper -import android.os.Message -import android.os.UserHandle -import android.os.UserManager -import android.provider.DeviceConfig -import com.android.internal.annotations.VisibleForTesting -import com.android.internal.config.sysui.SystemUiDeviceConfigFlags -import com.android.systemui.Dependency.BG_HANDLER_NAME -import com.android.systemui.Dependency.MAIN_HANDLER_NAME -import com.android.systemui.R -import com.android.systemui.appops.AppOpItem -import com.android.systemui.appops.AppOpsController -import com.android.systemui.Dumpable -import java.io.FileDescriptor -import java.io.PrintWriter -import java.lang.ref.WeakReference -import javax.inject.Inject -import javax.inject.Named -import javax.inject.Singleton - -fun isPermissionsHubEnabled() = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false) - -@Singleton -class PrivacyItemController @Inject constructor( - val context: Context, - private val appOpsController: AppOpsController, - @Named(MAIN_HANDLER_NAME) private val uiHandler: Handler, - @Named(BG_HANDLER_NAME) private val bgHandler: Handler -) : Dumpable { - - @VisibleForTesting - internal companion object { - val OPS = intArrayOf(AppOpsManager.OP_CAMERA, - AppOpsManager.OP_RECORD_AUDIO, - AppOpsManager.OP_COARSE_LOCATION, - AppOpsManager.OP_FINE_LOCATION) - val intents = listOf(Intent.ACTION_USER_FOREGROUND, - Intent.ACTION_MANAGED_PROFILE_ADDED, - Intent.ACTION_MANAGED_PROFILE_REMOVED) - const val TAG = "PrivacyItemController" - const val SYSTEM_UID = 1000 - const val MSG_ADD_CALLBACK = 0 - const val MSG_REMOVE_CALLBACK = 1 - const val MSG_UPDATE_LISTENING_STATE = 2 - } - - @VisibleForTesting - internal var privacyList = emptyList<PrivacyItem>() - @Synchronized get() = field.toList() // Returns a shallow copy of the list - @Synchronized set - - private val userManager = context.getSystemService(UserManager::class.java) - private var currentUserIds = emptyList<Int>() - private var listening = false - val systemApp = - PrivacyApplication(context.getString(R.string.device_services), SYSTEM_UID, context) - private val callbacks = mutableListOf<WeakReference<Callback>>() - private val messageHandler = H(WeakReference(this), uiHandler.looper) - - private val notifyChanges = Runnable { - val list = privacyList - callbacks.forEach { it.get()?.privacyChanged(list) } - } - - private val updateListAndNotifyChanges = Runnable { - updatePrivacyList() - uiHandler.post(notifyChanges) - } - - private var indicatorsAvailable = isPermissionsHubEnabled() - @VisibleForTesting - internal val devicePropertyChangedListener = - object : DeviceConfig.OnPropertyChangedListener { - override fun onPropertyChanged(namespace: String, name: String, value: String?) { - if (DeviceConfig.NAMESPACE_PRIVACY.equals(namespace) && - SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED.equals(name)) { - indicatorsAvailable = java.lang.Boolean.parseBoolean(value) - messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE) - messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE) - } - } - } - - private val cb = object : AppOpsController.Callback { - override fun onActiveStateChanged( - code: Int, - uid: Int, - packageName: String, - active: Boolean - ) { - val userId = UserHandle.getUserId(uid) - if (userId in currentUserIds) { - update(false) - } - } - } - - @VisibleForTesting - internal var userSwitcherReceiver = Receiver() - set(value) { - context.unregisterReceiver(field) - field = value - registerReceiver() - } - - init { - DeviceConfig.addOnPropertyChangedListener( - DeviceConfig.NAMESPACE_PRIVACY, context.mainExecutor, devicePropertyChangedListener) - } - - private fun unregisterReceiver() { - context.unregisterReceiver(userSwitcherReceiver) - } - - private fun registerReceiver() { - context.registerReceiverAsUser(userSwitcherReceiver, UserHandle.ALL, IntentFilter().apply { - intents.forEach { - addAction(it) - } - }, null, null) - } - - private fun update(updateUsers: Boolean) { - if (updateUsers) { - val currentUser = ActivityManager.getCurrentUser() - currentUserIds = userManager.getProfiles(currentUser).map { it.id } - } - bgHandler.post(updateListAndNotifyChanges) - } - - /** - * Updates listening status based on whether there are callbacks and the indicators are enabled - * - * This is only called from private (add/remove)Callback and from the config listener, all in - * main thread. - */ - private fun setListeningState() { - val listen = !callbacks.isEmpty() and indicatorsAvailable - if (listening == listen) return - listening = listen - if (listening) { - appOpsController.addCallback(OPS, cb) - registerReceiver() - update(true) - } else { - appOpsController.removeCallback(OPS, cb) - unregisterReceiver() - // Make sure that we remove all indicators and notify listeners if we are not - // listening anymore due to indicators being disabled - update(false) - } - } - - private fun addCallback(callback: WeakReference<Callback>) { - callbacks.add(callback) - if (callbacks.isNotEmpty() && !listening) { - messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE) - messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE) - } - // Notify this callback if we didn't set to listening - else if (listening) uiHandler.post(NotifyChangesToCallback(callback.get(), privacyList)) - } - - private fun removeCallback(callback: WeakReference<Callback>) { - // Removes also if the callback is null - callbacks.removeIf { it.get()?.equals(callback.get()) ?: true } - if (callbacks.isEmpty()) { - messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE) - messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE) - } - } - - fun addCallback(callback: Callback) { - messageHandler.obtainMessage(MSG_ADD_CALLBACK, callback).sendToTarget() - } - - fun removeCallback(callback: Callback) { - messageHandler.obtainMessage(MSG_REMOVE_CALLBACK, callback).sendToTarget() - } - - private fun updatePrivacyList() { - if (!listening) { - privacyList = emptyList() - return - } - val list = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) } - .mapNotNull { toPrivacyItem(it) }.distinct() - privacyList = list - } - - private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { - val type: PrivacyType = when (appOpItem.code) { - AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA - AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION - AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION - AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE - else -> return null - } - if (appOpItem.uid == SYSTEM_UID) return PrivacyItem(type, systemApp) - val app = PrivacyApplication(appOpItem.packageName, appOpItem.uid, context) - return PrivacyItem(type, app) - } - - // Used by containing class to get notified of changes - interface Callback { - fun privacyChanged(privacyItems: List<PrivacyItem>) - } - - internal inner class Receiver : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - if (intent?.action in intents) { - update(true) - } - } - } - - private class NotifyChangesToCallback( - private val callback: Callback?, - private val list: List<PrivacyItem> - ) : Runnable { - override fun run() { - callback?.privacyChanged(list) - } - } - - override fun dump(fd: FileDescriptor?, pw: PrintWriter?, args: Array<out String>?) { - pw?.println("PrivacyItemController state:") - pw?.println(" Listening: $listening") - pw?.println(" Current user ids: $currentUserIds") - pw?.println(" Privacy Items:") - privacyList.forEach { - pw?.print(" ") - pw?.println(it.toString()) - } - pw?.println(" Callbacks:") - callbacks.forEach { - it.get()?.let { - pw?.print(" ") - pw?.println(it.toString()) - } - } - } - - private class H( - private val outerClass: WeakReference<PrivacyItemController>, - looper: Looper - ) : Handler(looper) { - override fun handleMessage(msg: Message) { - super.handleMessage(msg) - when (msg.what) { - MSG_UPDATE_LISTENING_STATE -> outerClass.get()?.setListeningState() - - MSG_ADD_CALLBACK -> { - if (msg.obj !is PrivacyItemController.Callback) return - outerClass.get()?.addCallback( - WeakReference(msg.obj as PrivacyItemController.Callback)) - } - - MSG_REMOVE_CALLBACK -> { - if (msg.obj !is PrivacyItemController.Callback) return - outerClass.get()?.removeCallback( - WeakReference(msg.obj as PrivacyItemController.Callback)) - } - else -> {} - } - } - } -}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 410a13ee4730..d59e251563c7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -32,30 +32,24 @@ import android.graphics.Color; import android.graphics.Rect; import android.media.AudioManager; import android.os.Handler; -import android.os.Looper; import android.provider.AlarmClock; -import android.provider.DeviceConfig; import android.provider.Settings; import android.service.notification.ZenModeConfig; import android.text.format.DateUtils; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; -import android.util.StatsLog; import android.view.ContextThemeWrapper; import android.view.DisplayCutout; import android.view.View; import android.view.WindowInsets; import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.RelativeLayout; -import android.widget.Space; import android.widget.TextView; import androidx.annotation.VisibleForTesting; -import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.settingslib.Utils; import com.android.systemui.BatteryMeterView; import com.android.systemui.DualToneHandler; @@ -63,11 +57,6 @@ import com.android.systemui.R; 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.PrivacyDialogBuilder; -import com.android.systemui.privacy.PrivacyItem; -import com.android.systemui.privacy.PrivacyItemController; -import com.android.systemui.privacy.PrivacyItemControllerKt; import com.android.systemui.qs.QSDetail.Callback; import com.android.systemui.statusbar.phone.PhoneStatusBarView; import com.android.systemui.statusbar.phone.StatusBarIconController; @@ -78,8 +67,6 @@ import com.android.systemui.statusbar.policy.DateView; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.ZenModeController; -import java.util.ArrayList; -import java.util.List; import java.util.Locale; import java.util.Objects; @@ -121,7 +108,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements private TintedIconManager mIconManager; private TouchAnimator mStatusIconsAlphaAnimator; private TouchAnimator mHeaderTextContainerAlphaAnimator; - private TouchAnimator mPrivacyChipAlphaAnimator; private DualToneHandler mDualToneHandler; private View mSystemIconsView; @@ -141,12 +127,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements private View mRingerContainer; private Clock mClockView; private DateView mDateView; - private OngoingPrivacyChip mPrivacyChip; - private Space mSpace; private BatteryMeterView mBatteryRemainingIcon; - private boolean mPermissionsHubEnabled; - - private PrivacyItemController mPrivacyItemController; private final BroadcastReceiver mRingerReceiver = new BroadcastReceiver() { @Override @@ -156,41 +137,17 @@ public class QuickStatusBarHeader extends RelativeLayout implements } }; private boolean mHasTopCutout = false; - private boolean mPrivacyChipLogged = false; - - private final DeviceConfig.OnPropertyChangedListener mPropertyListener = - new DeviceConfig.OnPropertyChangedListener() { - @Override - public void onPropertyChanged(String namespace, String name, String value) { - if (DeviceConfig.NAMESPACE_PRIVACY.equals(namespace) - && SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED.equals( - name)) { - mPermissionsHubEnabled = Boolean.valueOf(value); - StatusIconContainer iconContainer = findViewById(R.id.statusIcons); - iconContainer.setIgnoredSlots(getIgnoredIconSlots()); - } - } - }; - - private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() { - @Override - public void privacyChanged(List<PrivacyItem> privacyItems) { - mPrivacyChip.setPrivacyList(privacyItems); - setChipVisibility(!privacyItems.isEmpty()); - } - }; @Inject public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, NextAlarmController nextAlarmController, ZenModeController zenModeController, StatusBarIconController statusBarIconController, - ActivityStarter activityStarter, PrivacyItemController privacyItemController) { + ActivityStarter activityStarter) { super(context, attrs); mAlarmController = nextAlarmController; mZenController = zenModeController; mStatusBarIconController = statusBarIconController; mActivityStarter = activityStarter; - mPrivacyItemController = privacyItemController; mDualToneHandler = new DualToneHandler( new ContextThemeWrapper(context, R.style.QSHeaderTheme)); } @@ -203,8 +160,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mSystemIconsView = findViewById(R.id.quick_status_bar_system_icons); mQuickQsStatusIcons = findViewById(R.id.quick_qs_status_icons); StatusIconContainer iconContainer = findViewById(R.id.statusIcons); - // Ignore privacy icons because they show in the space above QQS - iconContainer.addIgnoredSlots(getIgnoredIconSlots()); iconContainer.setShouldRestrictIcons(false); mIconManager = new TintedIconManager(iconContainer); @@ -218,9 +173,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mRingerModeIcon = findViewById(R.id.ringer_mode_icon); mRingerModeTextView = findViewById(R.id.ringer_mode_text); mRingerContainer = findViewById(R.id.ringer_container); - mRingerContainer.setOnClickListener(this::onClick); - mPrivacyChip = findViewById(R.id.privacy_chip); - mPrivacyChip.setOnClickListener(this::onClick); mCarrierGroup = findViewById(R.id.carrier_group); @@ -243,7 +195,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mClockView = findViewById(R.id.clock); mClockView.setOnClickListener(this); mDateView = findViewById(R.id.date); - mSpace = findViewById(R.id.space); // Tint for the battery icons are handled in setupHost() mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon); @@ -254,26 +205,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE); mRingerModeTextView.setSelected(true); mNextAlarmTextView.setSelected(true); - - mPermissionsHubEnabled = PrivacyItemControllerKt.isPermissionsHubEnabled(); - // Change the ignored slots when DeviceConfig flag changes - DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_PRIVACY, - mContext.getMainExecutor(), mPropertyListener); - - } - - private List<String> getIgnoredIconSlots() { - ArrayList<String> ignored = new ArrayList<>(); - ignored.add(mContext.getResources().getString( - com.android.internal.R.string.status_bar_camera)); - ignored.add(mContext.getResources().getString( - com.android.internal.R.string.status_bar_microphone)); - if (mPermissionsHubEnabled) { - ignored.add(mContext.getResources().getString( - com.android.internal.R.string.status_bar_location)); - } - - return ignored; } private void updateStatusText() { @@ -287,21 +218,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements } } - private void setChipVisibility(boolean chipVisible) { - if (chipVisible && mPermissionsHubEnabled) { - mPrivacyChip.setVisibility(View.VISIBLE); - // Makes sure that the chip is logged as viewed at most once each time QS is opened - // mListening makes sure that the callback didn't return after the user closed QS - if (!mPrivacyChipLogged && mListening) { - mPrivacyChipLogged = true; - StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED, - StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_VIEWED); - } - } else { - mPrivacyChip.setVisibility(View.GONE); - } - } - private boolean updateRingerStatus() { boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE; CharSequence originalRingerText = mRingerModeTextView.getText(); @@ -408,7 +324,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements updateStatusIconAlphaAnimator(); updateHeaderTextContainerAlphaAnimator(); - updatePrivacyChipAlphaAnimator(); } private void updateStatusIconAlphaAnimator() { @@ -423,12 +338,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements .build(); } - private void updatePrivacyChipAlphaAnimator() { - mPrivacyChipAlphaAnimator = new TouchAnimator.Builder() - .addFloat(mPrivacyChip, "alpha", 1, 0, 1) - .build(); - } - public void setExpanded(boolean expanded) { if (mExpanded == expanded) return; mExpanded = expanded; @@ -467,10 +376,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mHeaderTextContainerView.setVisibility(INVISIBLE); } } - if (mPrivacyChipAlphaAnimator != null) { - mPrivacyChip.setExpanded(expansionFraction > 0.5); - mPrivacyChipAlphaAnimator.setPosition(keyguardExpansionFraction); - } } public void disable(int state1, int state2, boolean animate) { @@ -503,21 +408,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mSystemIconsView.setPadding(padding.first, 0, padding.second, 0); } - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSpace.getLayoutParams(); - if (cutout != null) { - Rect topCutout = cutout.getBoundingRectTop(); - if (topCutout.isEmpty()) { - mHasTopCutout = false; - lp.width = 0; - mSpace.setVisibility(View.GONE); - } else { - mHasTopCutout = true; - lp.width = topCutout.width(); - mSpace.setVisibility(View.VISIBLE); - } - } - mSpace.setLayoutParams(lp); - setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE); return super.onApplyWindowInsets(insets); } @@ -542,13 +432,10 @@ public class QuickStatusBarHeader extends RelativeLayout implements mAlarmController.addCallback(this); mContext.registerReceiver(mRingerReceiver, new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)); - mPrivacyItemController.addCallback(mPICCallback); } else { mZenController.removeCallback(this); mAlarmController.removeCallback(this); - mPrivacyItemController.removeCallback(mPICCallback); mContext.unregisterReceiver(mRingerReceiver); - mPrivacyChipLogged = false; } } @@ -566,18 +453,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mActivityStarter.postStartActivityDismissingKeyguard(new Intent( AlarmClock.ACTION_SHOW_ALARMS), 0); } - } else if (v == mPrivacyChip) { - // Makes sure that the builder is grabbed as soon as the chip is pressed - PrivacyDialogBuilder builder = mPrivacyChip.getBuilder(); - if (builder.getAppsAndTypes().size() == 0) return; - Handler mUiHandler = new Handler(Looper.getMainLooper()); - StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED, - StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_CLICKED); - mUiHandler.post(() -> { - mActivityStarter.postStartActivityDismissingKeyguard( - new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0); - mHost.collapsePanels(); - }); } else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) { mActivityStarter.postStartActivityDismissingKeyguard(new Intent( Settings.ACTION_SOUND_SETTINGS), 0); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index ee4387952792..17c200eaef6a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -42,10 +42,6 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.UiOffloadThread; -import com.android.systemui.privacy.PrivacyItem; -import com.android.systemui.privacy.PrivacyItemController; -import com.android.systemui.privacy.PrivacyItemControllerKt; -import com.android.systemui.privacy.PrivacyType; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.statusbar.CommandQueue; @@ -66,9 +62,6 @@ import com.android.systemui.statusbar.policy.SensorPrivacyController; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.ZenModeController; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.List; import java.util.Locale; /** @@ -83,12 +76,12 @@ public class PhoneStatusBarPolicy ZenModeController.Callback, DeviceProvisionedListener, KeyguardMonitor.Callback, - PrivacyItemController.Callback, LocationController.LocationChangeCallback { private static final String TAG = "PhoneStatusBarPolicy"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - public static final int LOCATION_STATUS_ICON_ID = PrivacyType.TYPE_LOCATION.getIconId(); + public static final int LOCATION_STATUS_ICON_ID = + com.android.internal.R.drawable.perm_group_location; private final String mSlotCast; private final String mSlotHotspot; @@ -102,8 +95,6 @@ public class PhoneStatusBarPolicy private final String mSlotHeadset; private final String mSlotDataSaver; private final String mSlotLocation; - private final String mSlotMicrophone; - private final String mSlotCamera; private final String mSlotSensorsOff; private final Context mContext; @@ -121,7 +112,6 @@ public class PhoneStatusBarPolicy private final DeviceProvisionedController mProvisionedController; private final KeyguardMonitor mKeyguardMonitor; private final LocationController mLocationController; - private final PrivacyItemController mPrivacyItemController; private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); private final SensorPrivacyController mSensorPrivacyController; @@ -154,7 +144,6 @@ public class PhoneStatusBarPolicy mProvisionedController = Dependency.get(DeviceProvisionedController.class); mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); mLocationController = Dependency.get(LocationController.class); - mPrivacyItemController = Dependency.get(PrivacyItemController.class); mSensorPrivacyController = Dependency.get(SensorPrivacyController.class); mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast); @@ -170,8 +159,6 @@ public class PhoneStatusBarPolicy mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset); mSlotDataSaver = context.getString(com.android.internal.R.string.status_bar_data_saver); mSlotLocation = context.getString(com.android.internal.R.string.status_bar_location); - mSlotMicrophone = context.getString(com.android.internal.R.string.status_bar_microphone); - mSlotCamera = context.getString(com.android.internal.R.string.status_bar_camera); mSlotSensorsOff = context.getString(com.android.internal.R.string.status_bar_sensors_off); // listen for broadcasts @@ -231,13 +218,6 @@ public class PhoneStatusBarPolicy context.getString(R.string.accessibility_data_saver_on)); mIconController.setIconVisibility(mSlotDataSaver, false); - // privacy items - mIconController.setIcon(mSlotMicrophone, PrivacyType.TYPE_MICROPHONE.getIconId(), - PrivacyType.TYPE_MICROPHONE.getName(mContext)); - mIconController.setIconVisibility(mSlotMicrophone, false); - mIconController.setIcon(mSlotCamera, PrivacyType.TYPE_CAMERA.getIconId(), - PrivacyType.TYPE_CAMERA.getName(mContext)); - mIconController.setIconVisibility(mSlotCamera, false); mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID, mContext.getString(R.string.accessibility_location_active)); mIconController.setIconVisibility(mSlotLocation, false); @@ -257,7 +237,6 @@ public class PhoneStatusBarPolicy mNextAlarmController.addCallback(mNextAlarmCallback); mDataSaver.addCallback(this); mKeyguardMonitor.addCallback(this); - mPrivacyItemController.addCallback(this); mSensorPrivacyController.addCallback(mSensorPrivacyListener); mLocationController.addCallback(this); @@ -601,46 +580,9 @@ public class PhoneStatusBarPolicy mIconController.setIconVisibility(mSlotDataSaver, isDataSaving); } - @Override // PrivacyItemController.Callback - public void privacyChanged(List<PrivacyItem> privacyItems) { - updatePrivacyItems(privacyItems); - } - - private void updatePrivacyItems(List<PrivacyItem> items) { - boolean showCamera = false; - boolean showMicrophone = false; - boolean showLocation = false; - for (PrivacyItem item : items) { - if (item == null /* b/124234367 */) { - if (DEBUG) { - Log.e(TAG, "updatePrivacyItems - null item found"); - StringWriter out = new StringWriter(); - mPrivacyItemController.dump(null, new PrintWriter(out), null); - Log.e(TAG, out.toString()); - } - continue; - } - switch (item.getPrivacyType()) { - case TYPE_CAMERA: - showCamera = true; - break; - case TYPE_LOCATION: - showLocation = true; - break; - case TYPE_MICROPHONE: - showMicrophone = true; - break; - } - } - - mIconController.setIconVisibility(mSlotCamera, showCamera); - mIconController.setIconVisibility(mSlotMicrophone, showMicrophone); - mIconController.setIconVisibility(mSlotLocation, showLocation); - } - @Override public void onLocationActiveChanged(boolean active) { - if (!PrivacyItemControllerKt.isPermissionsHubEnabled()) updateLocation(); + updateLocation(); } // Updates the status view based on the current state of location requests. diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java index cc31531c90a7..bd7f897dc1c0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java @@ -25,11 +25,9 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.app.AppOpsManager; import android.content.pm.PackageManager; @@ -55,7 +53,6 @@ public class AppOpsControllerTest extends SysuiTestCase { private static final String TEST_PACKAGE_NAME = "test"; private static final int TEST_UID = UserHandle.getUid(0, 0); private static final int TEST_UID_OTHER = UserHandle.getUid(1, 0); - private static final int TEST_UID_NON_USER_SENSITIVE = UserHandle.getUid(2, 0); @Mock private AppOpsManager mAppOpsManager; @@ -74,18 +71,6 @@ public class AppOpsControllerTest extends SysuiTestCase { getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager); - // All permissions of TEST_UID and TEST_UID_OTHER are user sensitive. None of - // TEST_UID_NON_USER_SENSITIVE are user sensitive. - getContext().setMockPackageManager(mPackageManager); - when(mPackageManager.getPermissionFlags(anyString(), anyString(), - eq(UserHandle.getUserHandleForUid(TEST_UID)))).thenReturn( - PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); - when(mPackageManager.getPermissionFlags(anyString(), anyString(), - eq(UserHandle.getUserHandleForUid(TEST_UID_OTHER)))).thenReturn( - PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); - when(mPackageManager.getPermissionFlags(anyString(), anyString(), - eq(UserHandle.getUserHandleForUid(TEST_UID_NON_USER_SENSITIVE)))).thenReturn(0); - mController = new AppOpsControllerImpl(mContext, Dependency.get(Dependency.BG_LOOPER)); } @@ -178,14 +163,6 @@ public class AppOpsControllerTest extends SysuiTestCase { } @Test - public void nonUserSensitiveOpsAreIgnored() { - mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO, - TEST_UID_NON_USER_SENSITIVE, TEST_PACKAGE_NAME, true); - assertEquals(0, mController.getActiveAppOpsForUser( - UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE)).size()); - } - - @Test public void opNotedScheduledForRemoval() { mController.setBGHandler(mMockHandler); mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt deleted file mode 100644 index 6302f9d56dc3..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt +++ /dev/null @@ -1,77 +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 androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.systemui.SysuiTestCase -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class PrivacyDialogBuilderTest : SysuiTestCase() { - - companion object { - val TEST_UID = 1 - } - - @Test - fun testGenerateAppsList() { - val bar2 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication( - "Bar", TEST_UID, context)) - val bar3 = PrivacyItem(Privacy.TYPE_LOCATION, PrivacyApplication( - "Bar", TEST_UID, context)) - val foo0 = PrivacyItem(Privacy.TYPE_MICROPHONE, PrivacyApplication( - "Foo", TEST_UID, context)) - val baz1 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication( - "Baz", TEST_UID, context)) - - val items = listOf(bar2, foo0, baz1, bar3) - - val textBuilder = PrivacyDialogBuilder(context, items) - - val list = textBuilder.appsAndTypes - assertEquals(3, list.size) - val appsList = list.map { it.first } - val typesList = list.map { it.second } - // List is sorted by number of types and then by types - assertEquals(listOf("Bar", "Baz", "Foo"), appsList.map { it.packageName }) - assertEquals(listOf(Privacy.TYPE_CAMERA, Privacy.TYPE_LOCATION), typesList[0]) - assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[1]) - assertEquals(listOf(Privacy.TYPE_MICROPHONE), typesList[2]) - } - - @Test - fun testOrder() { - // We want location to always go last, so it will go in the "+ other apps" - val appCamera = PrivacyItem(PrivacyType.TYPE_CAMERA, - PrivacyApplication("Camera", TEST_UID, context)) - val appMicrophone = - PrivacyItem(PrivacyType.TYPE_MICROPHONE, - PrivacyApplication("Microphone", TEST_UID, context)) - val appLocation = - PrivacyItem(PrivacyType.TYPE_LOCATION, - PrivacyApplication("Location", TEST_UID, context)) - - val items = listOf(appLocation, appMicrophone, appCamera) - val textBuilder = PrivacyDialogBuilder(context, items) - val appList = textBuilder.appsAndTypes.map { it.first }.map { it.packageName } - assertEquals(listOf("Camera", "Microphone", "Location"), appList) - } -}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt deleted file mode 100644 index e2e0bb151228..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt +++ /dev/null @@ -1,293 +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.ActivityManager -import android.app.AppOpsManager -import android.content.Context -import android.content.Intent -import android.content.pm.UserInfo -import android.os.Handler -import android.os.UserHandle -import android.os.UserManager -import android.provider.DeviceConfig -import android.provider.Settings.RESET_MODE_PACKAGE_DEFAULTS -import android.testing.AndroidTestingRunner -import android.testing.TestableLooper -import android.testing.TestableLooper.RunWithLooper -import androidx.test.filters.SmallTest -import com.android.internal.config.sysui.SystemUiDeviceConfigFlags -import com.android.systemui.Dependency -import com.android.systemui.R -import com.android.systemui.SysuiTestCase -import com.android.systemui.appops.AppOpItem -import com.android.systemui.appops.AppOpsController -import org.hamcrest.Matchers.hasItem -import org.hamcrest.Matchers.not -import org.hamcrest.Matchers.nullValue -import org.junit.After -import org.junit.Assert.assertEquals -import org.junit.Assert.assertThat -import org.junit.Assert.assertTrue -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentCaptor -import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.anyInt -import org.mockito.ArgumentMatchers.anyList -import org.mockito.ArgumentMatchers.eq -import org.mockito.Captor -import org.mockito.Mock -import org.mockito.Mockito.atLeastOnce -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock -import org.mockito.Mockito.never -import org.mockito.Mockito.reset -import org.mockito.Mockito.spy -import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyNoMoreInteractions -import org.mockito.MockitoAnnotations - -@RunWith(AndroidTestingRunner::class) -@SmallTest -@RunWithLooper -class PrivacyItemControllerTest : SysuiTestCase() { - - companion object { - val CURRENT_USER_ID = ActivityManager.getCurrentUser() - val TEST_UID = CURRENT_USER_ID * UserHandle.PER_USER_RANGE - const val SYSTEM_UID = 1000 - const val TEST_PACKAGE_NAME = "test" - const val DEVICE_SERVICES_STRING = "Device services" - const val TAG = "PrivacyItemControllerTest" - fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture() - } - - @Mock - private lateinit var appOpsController: AppOpsController - @Mock - private lateinit var callback: PrivacyItemController.Callback - @Mock - private lateinit var userManager: UserManager - @Captor - private lateinit var argCaptor: ArgumentCaptor<List<PrivacyItem>> - @Captor - private lateinit var argCaptorCallback: ArgumentCaptor<AppOpsController.Callback> - - private lateinit var testableLooper: TestableLooper - private lateinit var privacyItemController: PrivacyItemController - private lateinit var handler: Handler - - fun PrivacyItemController(context: Context) = - PrivacyItemController(context, appOpsController, handler, handler) - - @Before - fun setup() { - MockitoAnnotations.initMocks(this) - testableLooper = TestableLooper.get(this) - handler = Handler(testableLooper.looper) - - appOpsController = mDependency.injectMockDependency(AppOpsController::class.java) - mDependency.injectTestDependency(Dependency.BG_HANDLER, handler) - mDependency.injectTestDependency(Dependency.MAIN_HANDLER, handler) - mContext.addMockSystemService(UserManager::class.java, userManager) - mContext.getOrCreateTestableResources().addOverride(R.string.device_services, - DEVICE_SERVICES_STRING) - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY, - SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, - "true", false) - - doReturn(listOf(object : UserInfo() { - init { - id = CURRENT_USER_ID - } - })).`when`(userManager).getProfiles(anyInt()) - - privacyItemController = PrivacyItemController(mContext) - } - - @After - fun tearDown() { - DeviceConfig.resetToDefaults(RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_PRIVACY) - } - - @Test - fun testSetListeningTrueByAddingCallback() { - privacyItemController.addCallback(callback) - testableLooper.processAllMessages() - verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), - any(AppOpsController.Callback::class.java)) - testableLooper.processAllMessages() - verify(callback).privacyChanged(anyList()) - } - - @Test - fun testSetListeningFalseByRemovingLastCallback() { - privacyItemController.addCallback(callback) - testableLooper.processAllMessages() - verify(appOpsController, never()).removeCallback(any(IntArray::class.java), - any(AppOpsController.Callback::class.java)) - privacyItemController.removeCallback(callback) - testableLooper.processAllMessages() - verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS), - any(AppOpsController.Callback::class.java)) - verify(callback).privacyChanged(emptyList()) - } - - @Test - fun testDistinctItems() { - doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0), - AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 1))) - .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) - - privacyItemController.addCallback(callback) - testableLooper.processAllMessages() - verify(callback).privacyChanged(capture(argCaptor)) - assertEquals(1, argCaptor.value.size) - } - - @Test - fun testSystemApps() { - doReturn(listOf(AppOpItem(AppOpsManager.OP_COARSE_LOCATION, SYSTEM_UID, TEST_PACKAGE_NAME, - 0))).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) - privacyItemController.addCallback(callback) - testableLooper.processAllMessages() - verify(callback).privacyChanged(capture(argCaptor)) - assertEquals(1, argCaptor.value.size) - assertEquals(context.getString(R.string.device_services), - argCaptor.value[0].application.applicationName) - } - - @Test - fun testRegisterReceiver_allUsers() { - val spiedContext = spy(mContext) - val itemController = PrivacyItemController(spiedContext) - itemController.addCallback(callback) - testableLooper.processAllMessages() - verify(spiedContext, atLeastOnce()).registerReceiverAsUser( - eq(itemController.userSwitcherReceiver), eq(UserHandle.ALL), any(), eq(null), - eq(null)) - verify(spiedContext, never()).unregisterReceiver(eq(itemController.userSwitcherReceiver)) - } - - @Test - fun testReceiver_ACTION_USER_FOREGROUND() { - privacyItemController.userSwitcherReceiver.onReceive(context, - Intent(Intent.ACTION_USER_FOREGROUND)) - verify(userManager).getProfiles(anyInt()) - } - - @Test - fun testReceiver_ACTION_MANAGED_PROFILE_ADDED() { - privacyItemController.userSwitcherReceiver.onReceive(context, - Intent(Intent.ACTION_MANAGED_PROFILE_ADDED)) - verify(userManager).getProfiles(anyInt()) - } - - @Test - fun testReceiver_ACTION_MANAGED_PROFILE_REMOVED() { - privacyItemController.userSwitcherReceiver.onReceive(context, - Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED)) - verify(userManager).getProfiles(anyInt()) - } - - @Test - fun testAddMultipleCallbacks() { - val otherCallback = mock(PrivacyItemController.Callback::class.java) - privacyItemController.addCallback(callback) - testableLooper.processAllMessages() - verify(callback).privacyChanged(anyList()) - - privacyItemController.addCallback(otherCallback) - testableLooper.processAllMessages() - verify(otherCallback).privacyChanged(anyList()) - // Adding a callback should not unnecessarily call previous ones - verifyNoMoreInteractions(callback) - } - - @Test - fun testMultipleCallbacksAreUpdated() { - doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) - - val otherCallback = mock(PrivacyItemController.Callback::class.java) - privacyItemController.addCallback(callback) - privacyItemController.addCallback(otherCallback) - testableLooper.processAllMessages() - reset(callback) - reset(otherCallback) - - verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback)) - argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true) - testableLooper.processAllMessages() - verify(callback).privacyChanged(anyList()) - verify(otherCallback).privacyChanged(anyList()) - } - - @Test - fun testRemoveCallback() { - doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) - val otherCallback = mock(PrivacyItemController.Callback::class.java) - privacyItemController.addCallback(callback) - privacyItemController.addCallback(otherCallback) - testableLooper.processAllMessages() - reset(callback) - reset(otherCallback) - - verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback)) - privacyItemController.removeCallback(callback) - argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true) - testableLooper.processAllMessages() - verify(callback, never()).privacyChanged(anyList()) - verify(otherCallback).privacyChanged(anyList()) - } - - @Test - fun testListShouldNotHaveNull() { - doReturn(listOf(AppOpItem(AppOpsManager.OP_ACTIVATE_VPN, TEST_UID, "", 0), - AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0))) - .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) - privacyItemController.addCallback(callback) - testableLooper.processAllMessages() - - verify(callback).privacyChanged(capture(argCaptor)) - assertEquals(1, argCaptor.value.size) - assertThat(argCaptor.value, not(hasItem(nullValue()))) - } - - @Test - fun testListShouldBeCopy() { - val list = listOf(PrivacyItem(PrivacyType.TYPE_CAMERA, - PrivacyApplication("", TEST_UID, mContext))) - privacyItemController.privacyList = list - val privacyList = privacyItemController.privacyList - assertEquals(list, privacyList) - assertTrue(list !== privacyList) - } - - @Test - fun testNotListeningWhenIndicatorsDisabled() { - privacyItemController.devicePropertyChangedListener.onPropertyChanged( - DeviceConfig.NAMESPACE_PRIVACY, - SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, - "false") - privacyItemController.addCallback(callback) - testableLooper.processAllMessages() - verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS), - any(AppOpsController.Callback::class.java)) - } -}
\ No newline at end of file |