Move ServiceListing to SettingsLib
Also tidy things up a bit Bug: 70902607 Test: RunSettingsRoboTests Change-Id: Id641beb601513bb4e34a098bf2729eb98954175d
This commit is contained in:
@@ -27,20 +27,16 @@ import com.android.settings.utils.ManagedServiceSettings;
|
|||||||
|
|
||||||
public class VrListenerSettings extends ManagedServiceSettings {
|
public class VrListenerSettings extends ManagedServiceSettings {
|
||||||
private static final String TAG = VrListenerSettings.class.getSimpleName();
|
private static final String TAG = VrListenerSettings.class.getSimpleName();
|
||||||
private static final Config CONFIG = getVrListenerConfig();
|
private static final Config CONFIG = new Config.Builder()
|
||||||
|
.setTag(TAG)
|
||||||
private static final Config getVrListenerConfig() {
|
.setSetting(Settings.Secure.ENABLED_VR_LISTENERS)
|
||||||
final Config c = new Config();
|
.setIntentAction(VrListenerService.SERVICE_INTERFACE)
|
||||||
c.tag = TAG;
|
.setPermission(android.Manifest.permission.BIND_VR_LISTENER_SERVICE)
|
||||||
c.setting = Settings.Secure.ENABLED_VR_LISTENERS;
|
.setNoun("vr listener")
|
||||||
c.intentAction = VrListenerService.SERVICE_INTERFACE;
|
.setWarningDialogTitle(R.string.vr_listener_security_warning_title)
|
||||||
c.permission = android.Manifest.permission.BIND_VR_LISTENER_SERVICE;
|
.setWarningDialogSummary(R.string.vr_listener_security_warning_summary)
|
||||||
c.noun = "vr listener";
|
.setEmptyText(R.string.no_vr_listeners)
|
||||||
c.warningDialogTitle = R.string.vr_listener_security_warning_title;
|
.build();
|
||||||
c.warningDialogSummary = R.string.vr_listener_security_warning_summary;
|
|
||||||
c.emptyText = R.string.no_vr_listeners;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Config getConfig() {
|
protected Config getConfig() {
|
||||||
|
@@ -19,8 +19,9 @@ package com.android.settings.notification;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.DialogInterface;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
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.overlay.FeatureFactory;
|
||||||
import com.android.settings.utils.ManagedServiceSettings;
|
import com.android.settings.utils.ManagedServiceSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings screen for managing notification listener permissions
|
||||||
|
*/
|
||||||
public class NotificationAccessSettings extends ManagedServiceSettings {
|
public class NotificationAccessSettings extends ManagedServiceSettings {
|
||||||
private static final String TAG = NotificationAccessSettings.class.getSimpleName();
|
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() {
|
private NotificationManager mNm;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
return MetricsEvent.NOTIFICATION_ACCESS;
|
return MetricsEvent.NOTIFICATION_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
mNm = context.getSystemService(NotificationManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Config getConfig() {
|
protected Config getConfig() {
|
||||||
return CONFIG;
|
return CONFIG;
|
||||||
@@ -109,14 +117,11 @@ public class NotificationAccessSettings extends ManagedServiceSettings {
|
|||||||
|
|
||||||
private static void disable(final NotificationAccessSettings parent, final ComponentName cn) {
|
private static void disable(final NotificationAccessSettings parent, final ComponentName cn) {
|
||||||
parent.mNm.setNotificationListenerAccessGranted(cn, false);
|
parent.mNm.setNotificationListenerAccessGranted(cn, false);
|
||||||
AsyncTask.execute(new Runnable() {
|
AsyncTask.execute(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!parent.mNm.isNotificationPolicyAccessGrantedForPackage(
|
if (!parent.mNm.isNotificationPolicyAccessGrantedForPackage(
|
||||||
cn.getPackageName())) {
|
cn.getPackageName())) {
|
||||||
parent.mNm.removeAutomaticZenRules(cn.getPackageName());
|
parent.mNm.removeAutomaticZenRules(cn.getPackageName());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,16 +158,10 @@ public class NotificationAccessSettings extends ManagedServiceSettings {
|
|||||||
.setMessage(summary)
|
.setMessage(summary)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setPositiveButton(R.string.notification_listener_disable_warning_confirm,
|
.setPositiveButton(R.string.notification_listener_disable_warning_confirm,
|
||||||
new DialogInterface.OnClickListener() {
|
(dialog, id) -> disable(parent, cn))
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
disable(parent, cn);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.notification_listener_disable_warning_cancel,
|
.setNegativeButton(R.string.notification_listener_disable_warning_cancel,
|
||||||
new DialogInterface.OnClickListener() {
|
(dialog, id) -> {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
// pass
|
// pass
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.create();
|
.create();
|
||||||
}
|
}
|
||||||
|
@@ -64,12 +64,12 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected static ManagedServiceSettings.Config getConditionProviderConfig() {
|
protected static ManagedServiceSettings.Config getConditionProviderConfig() {
|
||||||
final ManagedServiceSettings.Config c = new ManagedServiceSettings.Config();
|
return new ManagedServiceSettings.Config.Builder()
|
||||||
c.tag = TAG;
|
.setTag(TAG)
|
||||||
c.intentAction = ConditionProviderService.SERVICE_INTERFACE;
|
.setIntentAction(ConditionProviderService.SERVICE_INTERFACE)
|
||||||
c.permission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
|
.setPermission(android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE)
|
||||||
c.noun = "condition provider";
|
.setNoun("condition provider")
|
||||||
return c;
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -21,11 +21,9 @@ import android.app.ActivityManager;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.pm.PackageItemInfo;
|
import android.content.pm.PackageItemInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
@@ -33,8 +31,6 @@ import android.os.Bundle;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.support.v14.preference.SwitchPreference;
|
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.support.v7.preference.PreferenceScreen;
|
||||||
import android.util.IconDrawableFactory;
|
import android.util.IconDrawableFactory;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -46,8 +42,8 @@ import com.android.settings.Utils;
|
|||||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
import com.android.settings.notification.EmptyTextSettings;
|
import com.android.settings.notification.EmptyTextSettings;
|
||||||
import com.android.settings.widget.AppSwitchPreference;
|
import com.android.settings.widget.AppSwitchPreference;
|
||||||
|
import com.android.settingslib.applications.ServiceListing;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class ManagedServiceSettings extends EmptyTextSettings {
|
public abstract class ManagedServiceSettings extends EmptyTextSettings {
|
||||||
@@ -57,8 +53,7 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings {
|
|||||||
protected Context mContext;
|
protected Context mContext;
|
||||||
private PackageManager mPm;
|
private PackageManager mPm;
|
||||||
private DevicePolicyManager mDpm;
|
private DevicePolicyManager mDpm;
|
||||||
protected ServiceListing mServiceListing;
|
private ServiceListing mServiceListing;
|
||||||
protected NotificationManager mNm;
|
|
||||||
private IconDrawableFactory mIconDrawableFactory;
|
private IconDrawableFactory mIconDrawableFactory;
|
||||||
|
|
||||||
abstract protected Config getConfig();
|
abstract protected Config getConfig();
|
||||||
@@ -74,15 +69,15 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings {
|
|||||||
mContext = getActivity();
|
mContext = getActivity();
|
||||||
mPm = mContext.getPackageManager();
|
mPm = mContext.getPackageManager();
|
||||||
mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
mIconDrawableFactory = IconDrawableFactory.newInstance(mContext);
|
mIconDrawableFactory = IconDrawableFactory.newInstance(mContext);
|
||||||
mServiceListing = new ServiceListing(mContext, mConfig);
|
mServiceListing = new ServiceListing.Builder(mContext)
|
||||||
mServiceListing.addCallback(new ServiceListing.Callback() {
|
.setPermission(mConfig.permission)
|
||||||
@Override
|
.setIntentAction(mConfig.intentAction)
|
||||||
public void onServicesReloaded(List<ServiceInfo> services) {
|
.setNoun(mConfig.noun)
|
||||||
updateList(services);
|
.setSetting(mConfig.setting)
|
||||||
}
|
.setTag(mConfig.tag)
|
||||||
});
|
.build();
|
||||||
|
mServiceListing.addCallback(this::updateList);
|
||||||
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(mContext));
|
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(mContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +110,7 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings {
|
|||||||
|
|
||||||
final PreferenceScreen screen = getPreferenceScreen();
|
final PreferenceScreen screen = getPreferenceScreen();
|
||||||
screen.removeAll();
|
screen.removeAll();
|
||||||
Collections.sort(services, new PackageItemInfo.DisplayNameComparator(mPm));
|
services.sort(new PackageItemInfo.DisplayNameComparator(mPm));
|
||||||
for (ServiceInfo service : services) {
|
for (ServiceInfo service : services) {
|
||||||
final ComponentName cn = new ComponentName(service.packageName, service.name);
|
final ComponentName cn = new ComponentName(service.packageName, service.name);
|
||||||
CharSequence title = null;
|
CharSequence title = null;
|
||||||
@@ -144,12 +139,9 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings {
|
|||||||
service.packageName, managedProfileId)) {
|
service.packageName, managedProfileId)) {
|
||||||
pref.setSummary(R.string.work_profile_notification_access_blocked_summary);
|
pref.setSummary(R.string.work_profile_notification_access_blocked_summary);
|
||||||
}
|
}
|
||||||
pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
pref.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
final boolean enable = (boolean) newValue;
|
final boolean enable = (boolean) newValue;
|
||||||
return setEnabled(cn, summary, enable);
|
return setEnabled(cn, summary, enable);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
screen.addPreference(pref);
|
screen.addPreference(pref);
|
||||||
}
|
}
|
||||||
@@ -188,8 +180,8 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class ScaryWarningDialogFragment extends InstrumentedDialogFragment {
|
public static class ScaryWarningDialogFragment extends InstrumentedDialogFragment {
|
||||||
static final String KEY_COMPONENT = "c";
|
private static final String KEY_COMPONENT = "c";
|
||||||
static final String KEY_LABEL = "l";
|
private static final String KEY_LABEL = "l";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
@@ -222,29 +214,92 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings {
|
|||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setPositiveButton(R.string.allow,
|
.setPositiveButton(R.string.allow,
|
||||||
new DialogInterface.OnClickListener() {
|
(dialog, id) -> parent.enable(cn))
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
parent.enable(cn);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.deny,
|
.setNegativeButton(R.string.deny,
|
||||||
new DialogInterface.OnClickListener() {
|
(dialog, id) -> {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
// pass
|
// pass
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.create();
|
.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Config {
|
public static class Config {
|
||||||
public String tag;
|
public final String tag;
|
||||||
public String setting;
|
public final String setting;
|
||||||
public String intentAction;
|
public final String intentAction;
|
||||||
public String permission;
|
public final String permission;
|
||||||
public String noun;
|
public final String noun;
|
||||||
public int warningDialogTitle;
|
public final int warningDialogTitle;
|
||||||
public int warningDialogSummary;
|
public final int warningDialogSummary;
|
||||||
public int emptyText;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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<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);
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user