From 09d2d7176050818c61e95a26cc566a0ef41c8ba5 Mon Sep 17 00:00:00 2001 From: Tony Mantler Date: Wed, 20 Dec 2017 15:54:01 -0800 Subject: [PATCH] Move ServiceListing to SettingsLib Also tidy things up a bit Bug: 70902607 Test: RunSettingsRoboTests Change-Id: Id641beb601513bb4e34a098bf2729eb98954175d --- .../applications/VrListenerSettings.java | 24 +-- .../NotificationAccessSettings.java | 59 +++--- .../ZenModeAutomationSettings.java | 12 +- .../utils/ManagedServiceSettings.java | 137 ++++++++---- .../settings/utils/ServiceListing.java | 196 ------------------ 5 files changed, 141 insertions(+), 287 deletions(-) delete mode 100644 src/com/android/settings/utils/ServiceListing.java diff --git a/src/com/android/settings/applications/VrListenerSettings.java b/src/com/android/settings/applications/VrListenerSettings.java index e40e3f9fe6f..ea88ae43356 100644 --- a/src/com/android/settings/applications/VrListenerSettings.java +++ b/src/com/android/settings/applications/VrListenerSettings.java @@ -27,20 +27,16 @@ import com.android.settings.utils.ManagedServiceSettings; public class VrListenerSettings extends ManagedServiceSettings { private static final String TAG = VrListenerSettings.class.getSimpleName(); - private static final Config CONFIG = getVrListenerConfig(); - - private static final Config getVrListenerConfig() { - final Config c = new Config(); - c.tag = TAG; - c.setting = Settings.Secure.ENABLED_VR_LISTENERS; - c.intentAction = VrListenerService.SERVICE_INTERFACE; - c.permission = android.Manifest.permission.BIND_VR_LISTENER_SERVICE; - c.noun = "vr listener"; - c.warningDialogTitle = R.string.vr_listener_security_warning_title; - c.warningDialogSummary = R.string.vr_listener_security_warning_summary; - c.emptyText = R.string.no_vr_listeners; - return c; - } + private static final Config CONFIG = new Config.Builder() + .setTag(TAG) + .setSetting(Settings.Secure.ENABLED_VR_LISTENERS) + .setIntentAction(VrListenerService.SERVICE_INTERFACE) + .setPermission(android.Manifest.permission.BIND_VR_LISTENER_SERVICE) + .setNoun("vr listener") + .setWarningDialogTitle(R.string.vr_listener_security_warning_title) + .setWarningDialogSummary(R.string.vr_listener_security_warning_summary) + .setEmptyText(R.string.no_vr_listeners) + .build(); @Override protected Config getConfig() { diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java index af89f4904ff..4180a53721d 100644 --- a/src/com/android/settings/notification/NotificationAccessSettings.java +++ b/src/com/android/settings/notification/NotificationAccessSettings.java @@ -19,8 +19,9 @@ package com.android.settings.notification; import android.app.AlertDialog; import android.app.Dialog; import android.app.Fragment; +import android.app.NotificationManager; import android.content.ComponentName; -import android.content.DialogInterface; +import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; import android.provider.Settings; @@ -33,28 +34,35 @@ import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settings.utils.ManagedServiceSettings; +/** + * Settings screen for managing notification listener permissions + */ public class NotificationAccessSettings extends ManagedServiceSettings { private static final String TAG = NotificationAccessSettings.class.getSimpleName(); - private static final Config CONFIG = getNotificationListenerConfig(); + private static final Config CONFIG = new Config.Builder() + .setTag(TAG) + .setSetting(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS) + .setIntentAction(NotificationListenerService.SERVICE_INTERFACE) + .setPermission(android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE) + .setNoun("notification listener") + .setWarningDialogTitle(R.string.notification_listener_security_warning_title) + .setWarningDialogSummary(R.string.notification_listener_security_warning_summary) + .setEmptyText(R.string.no_notification_listeners) + .build(); - private static Config getNotificationListenerConfig() { - final Config c = new Config(); - c.tag = TAG; - c.setting = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS; - c.intentAction = NotificationListenerService.SERVICE_INTERFACE; - c.permission = android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE; - c.noun = "notification listener"; - c.warningDialogTitle = R.string.notification_listener_security_warning_title; - c.warningDialogSummary = R.string.notification_listener_security_warning_summary; - c.emptyText = R.string.no_notification_listeners; - return c; - } + private NotificationManager mNm; @Override public int getMetricsCategory() { return MetricsEvent.NOTIFICATION_ACCESS; } + @Override + public void onAttach(Context context) { + super.onAttach(context); + mNm = context.getSystemService(NotificationManager.class); + } + @Override protected Config getConfig() { return CONFIG; @@ -109,13 +117,10 @@ public class NotificationAccessSettings extends ManagedServiceSettings { private static void disable(final NotificationAccessSettings parent, final ComponentName cn) { parent.mNm.setNotificationListenerAccessGranted(cn, false); - AsyncTask.execute(new Runnable() { - @Override - public void run() { - if (!parent.mNm.isNotificationPolicyAccessGrantedForPackage( - cn.getPackageName())) { - parent.mNm.removeAutomaticZenRules(cn.getPackageName()); - } + AsyncTask.execute(() -> { + if (!parent.mNm.isNotificationPolicyAccessGrantedForPackage( + cn.getPackageName())) { + parent.mNm.removeAutomaticZenRules(cn.getPackageName()); } }); } @@ -153,16 +158,10 @@ public class NotificationAccessSettings extends ManagedServiceSettings { .setMessage(summary) .setCancelable(true) .setPositiveButton(R.string.notification_listener_disable_warning_confirm, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - disable(parent, cn); - } - }) + (dialog, id) -> disable(parent, cn)) .setNegativeButton(R.string.notification_listener_disable_warning_cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // pass - } + (dialog, id) -> { + // pass }) .create(); } diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java index 55d0fca8efd..6ce13c14635 100644 --- a/src/com/android/settings/notification/ZenModeAutomationSettings.java +++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java @@ -64,12 +64,12 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase { } protected static ManagedServiceSettings.Config getConditionProviderConfig() { - final ManagedServiceSettings.Config c = new ManagedServiceSettings.Config(); - c.tag = TAG; - c.intentAction = ConditionProviderService.SERVICE_INTERFACE; - c.permission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE; - c.noun = "condition provider"; - return c; + return new ManagedServiceSettings.Config.Builder() + .setTag(TAG) + .setIntentAction(ConditionProviderService.SERVICE_INTERFACE) + .setPermission(android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE) + .setNoun("condition provider") + .build(); } /** diff --git a/src/com/android/settings/utils/ManagedServiceSettings.java b/src/com/android/settings/utils/ManagedServiceSettings.java index d488dfe3ca2..d22234549ec 100644 --- a/src/com/android/settings/utils/ManagedServiceSettings.java +++ b/src/com/android/settings/utils/ManagedServiceSettings.java @@ -21,11 +21,9 @@ import android.app.ActivityManager; import android.app.AlertDialog; import android.app.Dialog; import android.app.Fragment; -import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; -import android.content.DialogInterface; import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; @@ -33,8 +31,6 @@ import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.Preference; -import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.PreferenceScreen; import android.util.IconDrawableFactory; import android.util.Log; @@ -46,8 +42,8 @@ import com.android.settings.Utils; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.notification.EmptyTextSettings; import com.android.settings.widget.AppSwitchPreference; +import com.android.settingslib.applications.ServiceListing; -import java.util.Collections; import java.util.List; public abstract class ManagedServiceSettings extends EmptyTextSettings { @@ -57,8 +53,7 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings { protected Context mContext; private PackageManager mPm; private DevicePolicyManager mDpm; - protected ServiceListing mServiceListing; - protected NotificationManager mNm; + private ServiceListing mServiceListing; private IconDrawableFactory mIconDrawableFactory; abstract protected Config getConfig(); @@ -74,15 +69,15 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings { mContext = getActivity(); mPm = mContext.getPackageManager(); mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); - mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); mIconDrawableFactory = IconDrawableFactory.newInstance(mContext); - mServiceListing = new ServiceListing(mContext, mConfig); - mServiceListing.addCallback(new ServiceListing.Callback() { - @Override - public void onServicesReloaded(List services) { - updateList(services); - } - }); + mServiceListing = new ServiceListing.Builder(mContext) + .setPermission(mConfig.permission) + .setIntentAction(mConfig.intentAction) + .setNoun(mConfig.noun) + .setSetting(mConfig.setting) + .setTag(mConfig.tag) + .build(); + mServiceListing.addCallback(this::updateList); setPreferenceScreen(getPreferenceManager().createPreferenceScreen(mContext)); } @@ -115,7 +110,7 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings { final PreferenceScreen screen = getPreferenceScreen(); screen.removeAll(); - Collections.sort(services, new PackageItemInfo.DisplayNameComparator(mPm)); + services.sort(new PackageItemInfo.DisplayNameComparator(mPm)); for (ServiceInfo service : services) { final ComponentName cn = new ComponentName(service.packageName, service.name); CharSequence title = null; @@ -144,12 +139,9 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings { service.packageName, managedProfileId)) { pref.setSummary(R.string.work_profile_notification_access_blocked_summary); } - pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean enable = (boolean) newValue; - return setEnabled(cn, summary, enable); - } + pref.setOnPreferenceChangeListener((preference, newValue) -> { + final boolean enable = (boolean) newValue; + return setEnabled(cn, summary, enable); }); screen.addPreference(pref); } @@ -188,8 +180,8 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings { } public static class ScaryWarningDialogFragment extends InstrumentedDialogFragment { - static final String KEY_COMPONENT = "c"; - static final String KEY_LABEL = "l"; + private static final String KEY_COMPONENT = "c"; + private static final String KEY_LABEL = "l"; @Override public int getMetricsCategory() { @@ -222,29 +214,92 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings { .setTitle(title) .setCancelable(true) .setPositiveButton(R.string.allow, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - parent.enable(cn); - } - }) + (dialog, id) -> parent.enable(cn)) .setNegativeButton(R.string.deny, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // pass - } + (dialog, id) -> { + // pass }) .create(); } } public static class Config { - public String tag; - public String setting; - public String intentAction; - public String permission; - public String noun; - public int warningDialogTitle; - public int warningDialogSummary; - public int emptyText; + public final String tag; + public final String setting; + public final String intentAction; + public final String permission; + public final String noun; + public final int warningDialogTitle; + public final int warningDialogSummary; + public final int emptyText; + + private Config(String tag, String setting, String intentAction, String permission, + String noun, int warningDialogTitle, int warningDialogSummary, int emptyText) { + this.tag = tag; + this.setting = setting; + this.intentAction = intentAction; + this.permission = permission; + this.noun = noun; + this.warningDialogTitle = warningDialogTitle; + this.warningDialogSummary = warningDialogSummary; + this.emptyText = emptyText; + } + + public static class Builder{ + private String mTag; + private String mSetting; + private String mIntentAction; + private String mPermission; + private String mNoun; + private int mWarningDialogTitle; + private int mWarningDialogSummary; + private int mEmptyText; + + public Builder setTag(String tag) { + mTag = tag; + return this; + } + + public Builder setSetting(String setting) { + mSetting = setting; + return this; + } + + public Builder setIntentAction(String intentAction) { + mIntentAction = intentAction; + return this; + } + + public Builder setPermission(String permission) { + mPermission = permission; + return this; + } + + public Builder setNoun(String noun) { + mNoun = noun; + return this; + } + + public Builder setWarningDialogTitle(int warningDialogTitle) { + mWarningDialogTitle = warningDialogTitle; + return this; + } + + public Builder setWarningDialogSummary(int warningDialogSummary) { + mWarningDialogSummary = warningDialogSummary; + return this; + } + + public Builder setEmptyText(int emptyText) { + mEmptyText = emptyText; + return this; + } + + public Config build() { + return new Config(mTag, mSetting, mIntentAction, mPermission, mNoun, + mWarningDialogTitle, mWarningDialogSummary, mEmptyText); + } + } } + } diff --git a/src/com/android/settings/utils/ServiceListing.java b/src/com/android/settings/utils/ServiceListing.java deleted file mode 100644 index 6a5fa103531..00000000000 --- a/src/com/android/settings/utils/ServiceListing.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2015 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.settings.utils; - -import android.app.ActivityManager; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.database.ContentObserver; -import android.net.Uri; -import android.os.Handler; -import android.provider.Settings; -import android.text.TextUtils; -import android.util.Slog; - -import com.android.settings.utils.ManagedServiceSettings.Config; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; - -public class ServiceListing { - private final ContentResolver mContentResolver; - private final Context mContext; - private final Config mConfig; - private final HashSet mEnabledServices = new HashSet(); - private final List mServices = new ArrayList(); - private final List mCallbacks = new ArrayList(); - - private boolean mListening; - - public ServiceListing(Context context, Config config) { - mContext = context; - mConfig = config; - mContentResolver = context.getContentResolver(); - } - - public void addCallback(Callback callback) { - mCallbacks.add(callback); - } - - public void removeCallback(Callback callback) { - mCallbacks.remove(callback); - } - - public void setListening(boolean listening) { - if (mListening == listening) return; - mListening = listening; - if (mListening) { - // listen for package changes - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_PACKAGE_ADDED); - filter.addAction(Intent.ACTION_PACKAGE_CHANGED); - filter.addAction(Intent.ACTION_PACKAGE_REMOVED); - filter.addAction(Intent.ACTION_PACKAGE_REPLACED); - filter.addDataScheme("package"); - mContext.registerReceiver(mPackageReceiver, filter); - mContentResolver.registerContentObserver(Settings.Secure.getUriFor(mConfig.setting), - false, mSettingsObserver); - } else { - mContext.unregisterReceiver(mPackageReceiver); - mContentResolver.unregisterContentObserver(mSettingsObserver); - } - } - - public static int getEnabledServicesCount(Config config, Context context) { - final String flat = Settings.Secure.getString(context.getContentResolver(), config.setting); - if (flat == null || "".equals(flat)) return 0; - final String[] components = flat.split(":"); - return components.length; - } - - public static int getServicesCount(Config c, PackageManager pm) { - return getServices(c, null, pm); - } - - protected static int getServices(Config c, List list, PackageManager pm) { - int services = 0; - if (list != null) { - list.clear(); - } - final int user = ActivityManager.getCurrentUser(); - - List installedServices = pm.queryIntentServicesAsUser( - new Intent(c.intentAction), - PackageManager.GET_SERVICES | PackageManager.GET_META_DATA, - user); - - for (int i = 0, count = installedServices.size(); i < count; i++) { - ResolveInfo resolveInfo = installedServices.get(i); - ServiceInfo info = resolveInfo.serviceInfo; - - if (!c.permission.equals(info.permission)) { - Slog.w(c.tag, "Skipping " + c.noun + " service " - + info.packageName + "/" + info.name - + ": it does not require the permission " - + c.permission); - continue; - } - if (list != null) { - list.add(info); - } - services++; - } - return services; - } - - private void saveEnabledServices() { - StringBuilder sb = null; - for (ComponentName cn : mEnabledServices) { - if (sb == null) { - sb = new StringBuilder(); - } else { - sb.append(':'); - } - sb.append(cn.flattenToString()); - } - Settings.Secure.putString(mContentResolver, mConfig.setting, - sb != null ? sb.toString() : ""); - } - - private void loadEnabledServices() { - mEnabledServices.clear(); - final String flat = Settings.Secure.getString(mContentResolver, mConfig.setting); - if (flat != null && !"".equals(flat)) { - final String[] names = flat.split(":"); - for (int i = 0; i < names.length; i++) { - final ComponentName cn = ComponentName.unflattenFromString(names[i]); - if (cn != null) { - mEnabledServices.add(cn); - } - } - } - } - - public List reload() { - loadEnabledServices(); - getServices(mConfig, mServices, mContext.getPackageManager()); - for (Callback callback : mCallbacks) { - callback.onServicesReloaded(mServices); - } - return mServices; - } - - public boolean isEnabled(ComponentName cn) { - return mEnabledServices.contains(cn); - } - - public void setEnabled(ComponentName cn, boolean enabled) { - if (enabled) { - mEnabledServices.add(cn); - } else { - mEnabledServices.remove(cn); - } - saveEnabledServices(); - } - - private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { - @Override - public void onChange(boolean selfChange, Uri uri) { - reload(); - } - }; - - private final BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - reload(); - } - }; - - public interface Callback { - void onServicesReloaded(List services); - } -}