Loading src/com/android/settings/applications/VrListenerSettings.java +10 −14 Original line number Diff line number Diff line Loading @@ -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() { Loading src/com/android/settings/notification/NotificationAccessSettings.java +30 −31 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 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 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 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; Loading Loading @@ -109,14 +117,11 @@ 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() { AsyncTask.execute(() -> { if (!parent.mNm.isNotificationPolicyAccessGrantedForPackage( cn.getPackageName())) { parent.mNm.removeAutomaticZenRules(cn.getPackageName()); } } }); } Loading Loading @@ -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) { (dialog, id) -> { // pass } }) .create(); } Loading src/com/android/settings/notification/ZenModeAutomationSettings.java +6 −6 Original line number Diff line number Diff line Loading @@ -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(); } /** Loading src/com/android/settings/utils/ManagedServiceSettings.java +96 −41 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 { Loading @@ -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(); Loading @@ -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<ServiceInfo> 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)); } Loading Loading @@ -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; Loading Loading @@ -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) { pref.setOnPreferenceChangeListener((preference, newValue) -> { final boolean enable = (boolean) newValue; return setEnabled(cn, summary, enable); } }); screen.addPreference(pref); } Loading Loading @@ -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() { Loading Loading @@ -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) { (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); } } } } src/com/android/settings/utils/ServiceListing.javadeleted 100644 → 0 +0 −196 Original line number Diff line number Diff line /* * 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<ComponentName> mEnabledServices = new HashSet<ComponentName>(); private final List<ServiceInfo> mServices = new ArrayList<ServiceInfo>(); private final List<Callback> mCallbacks = new ArrayList<Callback>(); 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<ServiceInfo> list, PackageManager pm) { int services = 0; if (list != null) { list.clear(); } final int user = ActivityManager.getCurrentUser(); List<ResolveInfo> 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<ServiceInfo> 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<ServiceInfo> services); } } Loading
src/com/android/settings/applications/VrListenerSettings.java +10 −14 Original line number Diff line number Diff line Loading @@ -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() { Loading
src/com/android/settings/notification/NotificationAccessSettings.java +30 −31 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 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 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 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; Loading Loading @@ -109,14 +117,11 @@ 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() { AsyncTask.execute(() -> { if (!parent.mNm.isNotificationPolicyAccessGrantedForPackage( cn.getPackageName())) { parent.mNm.removeAutomaticZenRules(cn.getPackageName()); } } }); } Loading Loading @@ -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) { (dialog, id) -> { // pass } }) .create(); } Loading
src/com/android/settings/notification/ZenModeAutomationSettings.java +6 −6 Original line number Diff line number Diff line Loading @@ -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(); } /** Loading
src/com/android/settings/utils/ManagedServiceSettings.java +96 −41 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 { Loading @@ -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(); Loading @@ -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<ServiceInfo> 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)); } Loading Loading @@ -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; Loading Loading @@ -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) { pref.setOnPreferenceChangeListener((preference, newValue) -> { final boolean enable = (boolean) newValue; return setEnabled(cn, summary, enable); } }); screen.addPreference(pref); } Loading Loading @@ -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() { Loading Loading @@ -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) { (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); } } } }
src/com/android/settings/utils/ServiceListing.javadeleted 100644 → 0 +0 −196 Original line number Diff line number Diff line /* * 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<ComponentName> mEnabledServices = new HashSet<ComponentName>(); private final List<ServiceInfo> mServices = new ArrayList<ServiceInfo>(); private final List<Callback> mCallbacks = new ArrayList<Callback>(); 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<ServiceInfo> list, PackageManager pm) { int services = 0; if (list != null) { list.clear(); } final int user = ActivityManager.getCurrentUser(); List<ResolveInfo> 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<ServiceInfo> 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<ServiceInfo> services); } }