TrustAgentSettings use DashboardFragment
- Remove dummy preference from trust_agent_setting.xml. - Build a controller to generate/manage a list of preferences. - Move some logics to the controller and add tests. Bug: 73899467 Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.security Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.core Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.search Test: atest SettingsGatewayTest UniquePreferenceTest Change-Id: Ideae0c1e7311d7647cf522e01592822e565a0ff7
This commit is contained in:
@@ -14,11 +14,10 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
<PreferenceScreen
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
android:key="trust_agents"
|
android:key="trust_agents"
|
||||||
android:title="@string/manage_trust_agents">
|
android:title="@string/manage_trust_agents"
|
||||||
|
settings:controller="com.android.settings.security.trustagent.TrustAgentsPreferenceController">
|
||||||
<!-- Needed so PreferenceGroupAdapter allows SwitchPreference to be
|
|
||||||
recycled. Removed in onResume -->
|
|
||||||
<SwitchPreference android:key="dummy_preference" />
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.security.trustagent;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
|
public class TrustAgentInfo implements Comparable<TrustAgentInfo> {
|
||||||
|
private final CharSequence mLabel;
|
||||||
|
private final ComponentName mComponentName;
|
||||||
|
private final Drawable mIcon;
|
||||||
|
|
||||||
|
public TrustAgentInfo(CharSequence label, ComponentName componentName, Drawable icon) {
|
||||||
|
mLabel = label;
|
||||||
|
mComponentName = componentName;
|
||||||
|
mIcon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getLabel() {
|
||||||
|
return mLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComponentName getComponentName() {
|
||||||
|
return mComponentName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drawable getIcon() {
|
||||||
|
return mIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (other instanceof TrustAgentInfo) {
|
||||||
|
return mComponentName.equals(((TrustAgentInfo) other).getComponentName());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(TrustAgentInfo other) {
|
||||||
|
return mComponentName.compareTo(other.getComponentName());
|
||||||
|
}
|
||||||
|
}
|
@@ -16,62 +16,22 @@
|
|||||||
|
|
||||||
package com.android.settings.security.trustagent;
|
package com.android.settings.security.trustagent;
|
||||||
|
|
||||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
|
||||||
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.provider.SearchIndexableResource;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.service.trust.TrustAgentService;
|
|
||||||
import androidx.preference.SwitchPreference;
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceGroup;
|
|
||||||
import android.util.ArrayMap;
|
|
||||||
import android.util.ArraySet;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsPreferenceFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settings.search.Indexable;
|
||||||
import com.android.settingslib.RestrictedSwitchPreference;
|
import com.android.settingslib.search.SearchIndexable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TrustAgentSettings extends SettingsPreferenceFragment implements
|
@SearchIndexable
|
||||||
Preference.OnPreferenceChangeListener {
|
public class TrustAgentSettings extends DashboardFragment {
|
||||||
private static final String SERVICE_INTERFACE = TrustAgentService.SERVICE_INTERFACE;
|
private static final String TAG = "TrustAgentSettings";
|
||||||
|
|
||||||
private ArrayMap<ComponentName, AgentInfo> mAvailableAgents;
|
|
||||||
private final ArraySet<ComponentName> mActiveAgents = new ArraySet<ComponentName>();
|
|
||||||
private LockPatternUtils mLockPatternUtils;
|
|
||||||
private DevicePolicyManager mDpm;
|
|
||||||
private TrustAgentManager mTrustAgentManager;
|
|
||||||
|
|
||||||
public static final class AgentInfo {
|
|
||||||
CharSequence label;
|
|
||||||
ComponentName component; // service that implements ITrustAgent
|
|
||||||
SwitchPreference preference;
|
|
||||||
public Drawable icon;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object other) {
|
|
||||||
if (other instanceof AgentInfo) {
|
|
||||||
return component.equals(((AgentInfo)other).component);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compareTo(AgentInfo other) {
|
|
||||||
return component.compareTo(other.component);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
@@ -84,122 +44,25 @@ public class TrustAgentSettings extends SettingsPreferenceFragment implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
protected String getLogTag() {
|
||||||
super.onCreate(icicle);
|
return TAG;
|
||||||
mDpm = getActivity().getSystemService(DevicePolicyManager.class);
|
|
||||||
mTrustAgentManager =
|
|
||||||
FeatureFactory.getFactory(getActivity()).getSecurityFeatureProvider()
|
|
||||||
.getTrustAgentManager();
|
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.trust_agent_settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
removePreference("dummy_preference");
|
|
||||||
updateAgents();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateAgents() {
|
|
||||||
final Context context = getActivity();
|
|
||||||
if (mAvailableAgents == null) {
|
|
||||||
mAvailableAgents = findAvailableTrustAgents();
|
|
||||||
}
|
|
||||||
if (mLockPatternUtils == null) {
|
|
||||||
mLockPatternUtils = new LockPatternUtils(getActivity());
|
|
||||||
}
|
|
||||||
loadActiveAgents();
|
|
||||||
PreferenceGroup category =
|
|
||||||
(PreferenceGroup) getPreferenceScreen().findPreference("trust_agents");
|
|
||||||
category.removeAll();
|
|
||||||
|
|
||||||
final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(context,
|
|
||||||
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId());
|
|
||||||
|
|
||||||
final int count = mAvailableAgents.size();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
AgentInfo agent = mAvailableAgents.valueAt(i);
|
|
||||||
final RestrictedSwitchPreference preference =
|
|
||||||
new RestrictedSwitchPreference(getPrefContext());
|
|
||||||
preference.useAdminDisabledSummary(true);
|
|
||||||
agent.preference = preference;
|
|
||||||
preference.setPersistent(false);
|
|
||||||
preference.setTitle(agent.label);
|
|
||||||
preference.setIcon(agent.icon);
|
|
||||||
preference.setPersistent(false);
|
|
||||||
preference.setOnPreferenceChangeListener(this);
|
|
||||||
preference.setChecked(mActiveAgents.contains(agent.component));
|
|
||||||
|
|
||||||
if (admin != null
|
|
||||||
&& mDpm.getTrustAgentConfiguration(null, agent.component) == null) {
|
|
||||||
preference.setChecked(false);
|
|
||||||
preference.setDisabledByAdmin(admin);
|
|
||||||
}
|
|
||||||
|
|
||||||
category.addPreference(agent.preference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadActiveAgents() {
|
|
||||||
List<ComponentName> activeTrustAgents = mLockPatternUtils.getEnabledTrustAgents(
|
|
||||||
UserHandle.myUserId());
|
|
||||||
if (activeTrustAgents != null) {
|
|
||||||
mActiveAgents.addAll(activeTrustAgents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveActiveAgents() {
|
|
||||||
mLockPatternUtils.setEnabledTrustAgents(mActiveAgents,
|
|
||||||
UserHandle.myUserId());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayMap<ComponentName, AgentInfo> findAvailableTrustAgents() {
|
|
||||||
PackageManager pm = getActivity().getPackageManager();
|
|
||||||
Intent trustAgentIntent = new Intent(SERVICE_INTERFACE);
|
|
||||||
List<ResolveInfo> resolveInfos = pm.queryIntentServices(trustAgentIntent,
|
|
||||||
PackageManager.GET_META_DATA);
|
|
||||||
|
|
||||||
ArrayMap<ComponentName, AgentInfo> agents = new ArrayMap<ComponentName, AgentInfo>();
|
|
||||||
final int count = resolveInfos.size();
|
|
||||||
agents.ensureCapacity(count);
|
|
||||||
for (int i = 0; i < count; i++ ) {
|
|
||||||
ResolveInfo resolveInfo = resolveInfos.get(i);
|
|
||||||
if (resolveInfo.serviceInfo == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!mTrustAgentManager.shouldProvideTrust(resolveInfo, pm)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ComponentName name = mTrustAgentManager.getComponentName(resolveInfo);
|
|
||||||
AgentInfo agentInfo = new AgentInfo();
|
|
||||||
agentInfo.label = resolveInfo.loadLabel(pm);
|
|
||||||
agentInfo.icon = resolveInfo.loadIcon(pm);
|
|
||||||
agentInfo.component = name;
|
|
||||||
agents.put(name, agentInfo);
|
|
||||||
}
|
|
||||||
return agents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
protected int getPreferenceScreenResId() {
|
||||||
if (preference instanceof SwitchPreference) {
|
return R.xml.trust_agent_settings;
|
||||||
final int count = mAvailableAgents.size();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
AgentInfo agent = mAvailableAgents.valueAt(i);
|
|
||||||
if (agent.preference == preference) {
|
|
||||||
if ((Boolean) newValue) {
|
|
||||||
if (!mActiveAgents.contains(agent.component)) {
|
|
||||||
mActiveAgents.add(agent.component);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mActiveAgents.remove(agent.component);
|
|
||||||
}
|
|
||||||
saveActiveAgents();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||||
|
new BaseSearchIndexProvider() {
|
||||||
|
@Override
|
||||||
|
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||||
|
Context context, boolean enabled) {
|
||||||
|
final List<SearchIndexableResource> result = new ArrayList<>();
|
||||||
|
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||||
|
sir.xmlResId = R.xml.trust_agent_settings;
|
||||||
|
result.add(sir);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.security.trustagent;
|
||||||
|
|
||||||
|
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
|
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.service.trust.TrustAgentService;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
import android.util.IconDrawableFactory;
|
||||||
|
|
||||||
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settings.security.SecurityFeatureProvider;
|
||||||
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
|
import com.android.settingslib.RestrictedSwitchPreference;
|
||||||
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
import androidx.preference.SwitchPreference;
|
||||||
|
|
||||||
|
public class TrustAgentsPreferenceController extends BasePreferenceController
|
||||||
|
implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnStart {
|
||||||
|
|
||||||
|
private static final Intent TRUST_AGENT_INTENT =
|
||||||
|
new Intent(TrustAgentService.SERVICE_INTERFACE);
|
||||||
|
|
||||||
|
private final ArrayMap<ComponentName, TrustAgentInfo> mAvailableAgents;
|
||||||
|
private final ArraySet<ComponentName> mActiveAgents;
|
||||||
|
private final DevicePolicyManager mDevicePolicyManager;
|
||||||
|
private final IconDrawableFactory mIconDrawableFactory;
|
||||||
|
private final LockPatternUtils mLockPatternUtils;
|
||||||
|
private final PackageManager mPackageManager;
|
||||||
|
private final TrustAgentManager mTrustAgentManager;
|
||||||
|
|
||||||
|
private PreferenceScreen mScreen;
|
||||||
|
|
||||||
|
public TrustAgentsPreferenceController(Context context, String key) {
|
||||||
|
super(context, key);
|
||||||
|
mAvailableAgents = new ArrayMap<>();
|
||||||
|
mActiveAgents = new ArraySet<>();
|
||||||
|
mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
|
||||||
|
mIconDrawableFactory = IconDrawableFactory.newInstance(context);
|
||||||
|
final SecurityFeatureProvider securityFeatureProvider =
|
||||||
|
FeatureFactory.getFactory(context).getSecurityFeatureProvider();
|
||||||
|
mTrustAgentManager = securityFeatureProvider.getTrustAgentManager();
|
||||||
|
mLockPatternUtils = securityFeatureProvider.getLockPatternUtils(context);
|
||||||
|
mPackageManager = context.getPackageManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
|
super.displayPreference(screen);
|
||||||
|
mScreen = screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAvailabilityStatus() {
|
||||||
|
return AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
updateAgents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAgents() {
|
||||||
|
findAvailableTrustAgents();
|
||||||
|
loadActiveAgents();
|
||||||
|
removeUselessExistingPreferences();
|
||||||
|
|
||||||
|
final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(mContext,
|
||||||
|
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId());
|
||||||
|
|
||||||
|
for (TrustAgentInfo agent : mAvailableAgents.values()) {
|
||||||
|
final ComponentName componentName = agent.getComponentName();
|
||||||
|
RestrictedSwitchPreference preference = (RestrictedSwitchPreference)
|
||||||
|
mScreen.findPreference(componentName.flattenToString());
|
||||||
|
if (preference == null) {
|
||||||
|
preference = new RestrictedSwitchPreference(mScreen.getContext());
|
||||||
|
}
|
||||||
|
preference.setKey(componentName.flattenToString());
|
||||||
|
preference.useAdminDisabledSummary(true);
|
||||||
|
preference.setTitle(agent.getLabel());
|
||||||
|
preference.setIcon(agent.getIcon());
|
||||||
|
preference.setOnPreferenceChangeListener(this);
|
||||||
|
preference.setChecked(mActiveAgents.contains(componentName));
|
||||||
|
if (admin != null && mDevicePolicyManager.getTrustAgentConfiguration(null /* admin */,
|
||||||
|
componentName) == null) {
|
||||||
|
preference.setChecked(false);
|
||||||
|
preference.setDisabledByAdmin(admin);
|
||||||
|
}
|
||||||
|
mScreen.addPreference(preference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadActiveAgents() {
|
||||||
|
final List<ComponentName> activeTrustAgents = mLockPatternUtils.getEnabledTrustAgents(
|
||||||
|
UserHandle.myUserId());
|
||||||
|
if (activeTrustAgents != null) {
|
||||||
|
mActiveAgents.addAll(activeTrustAgents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveActiveAgents() {
|
||||||
|
mLockPatternUtils.setEnabledTrustAgents(mActiveAgents, UserHandle.myUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findAvailableTrustAgents() {
|
||||||
|
final List<ResolveInfo> resolveInfos = mPackageManager.queryIntentServices(
|
||||||
|
TRUST_AGENT_INTENT, PackageManager.GET_META_DATA);
|
||||||
|
mAvailableAgents.clear();
|
||||||
|
for (ResolveInfo resolveInfo : resolveInfos) {
|
||||||
|
if (resolveInfo.serviceInfo == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!mTrustAgentManager.shouldProvideTrust(resolveInfo, mPackageManager)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final CharSequence label = resolveInfo.loadLabel(mPackageManager);
|
||||||
|
final ComponentName componentName = mTrustAgentManager.getComponentName(resolveInfo);
|
||||||
|
final Drawable icon = mIconDrawableFactory.getBadgedIcon(
|
||||||
|
resolveInfo.getComponentInfo().applicationInfo);
|
||||||
|
final TrustAgentInfo agentInfo = new TrustAgentInfo(label, componentName, icon);
|
||||||
|
mAvailableAgents.put(componentName, agentInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeUselessExistingPreferences() {
|
||||||
|
final int count = mScreen.getPreferenceCount();
|
||||||
|
if (count <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = count - 1; i >= 0; i--) {
|
||||||
|
final Preference pref = mScreen.getPreference(i);
|
||||||
|
final String[] names = TextUtils.split(pref.getKey(), "/");
|
||||||
|
final ComponentName componentName = new ComponentName(names[0], names[1]);
|
||||||
|
if (!mAvailableAgents.containsKey(componentName)) {
|
||||||
|
mScreen.removePreference(pref);
|
||||||
|
mActiveAgents.remove(componentName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
if (!(preference instanceof SwitchPreference)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (TrustAgentInfo agent : mAvailableAgents.values()) {
|
||||||
|
final ComponentName componentName = agent.getComponentName();
|
||||||
|
if (!TextUtils.equals(preference.getKey(), componentName.flattenToString())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((Boolean) newValue && !mActiveAgents.contains(componentName)) {
|
||||||
|
mActiveAgents.add(componentName);
|
||||||
|
} else {
|
||||||
|
mActiveAgents.remove(componentName);
|
||||||
|
}
|
||||||
|
saveActiveAgents();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -57,7 +57,6 @@ com.android.settings.network.ApnSettings
|
|||||||
com.android.settings.wifi.calling.WifiCallingSettingsForSub
|
com.android.settings.wifi.calling.WifiCallingSettingsForSub
|
||||||
com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment
|
com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment
|
||||||
com.android.settings.SetupRedactionInterstitial$SetupRedactionInterstitialFragment
|
com.android.settings.SetupRedactionInterstitial$SetupRedactionInterstitialFragment
|
||||||
com.android.settings.security.trustagent.TrustAgentSettings
|
|
||||||
com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment
|
com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment
|
||||||
com.android.settings.IccLockSettings
|
com.android.settings.IccLockSettings
|
||||||
com.android.settings.TetherSettings
|
com.android.settings.TetherSettings
|
||||||
|
@@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
package com.android.settings.security.trustagent;
|
package com.android.settings.security.trustagent;
|
||||||
|
|
||||||
import static com.android.settings.security.trustagent.TrustAgentListPreferenceController.PREF_KEY_SECURITY_CATEGORY;
|
import static com.android.settings.security.trustagent.TrustAgentListPreferenceController
|
||||||
import static com.android.settings.security.trustagent.TrustAgentListPreferenceController.PREF_KEY_TRUST_AGENT;
|
.PREF_KEY_SECURITY_CATEGORY;
|
||||||
|
import static com.android.settings.security.trustagent.TrustAgentListPreferenceController
|
||||||
|
.PREF_KEY_TRUST_AGENT;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
@@ -27,12 +29,8 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceCategory;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
@@ -52,6 +50,11 @@ import org.robolectric.annotation.Config;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceCategory;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
public class TrustAgentListPreferenceControllerTest {
|
public class TrustAgentListPreferenceControllerTest {
|
||||||
|
|
||||||
|
@@ -0,0 +1,231 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.security.trustagent;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.content.pm.ServiceInfo;
|
||||||
|
import android.service.trust.TrustAgentService;
|
||||||
|
|
||||||
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
|
||||||
|
import com.android.settingslib.RestrictedSwitchPreference;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.Shadows;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.annotation.Implementation;
|
||||||
|
import org.robolectric.annotation.Implements;
|
||||||
|
import org.robolectric.shadows.ShadowApplicationPackageManager;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(shadows = {
|
||||||
|
ShadowLockPatternUtils.class,
|
||||||
|
ShadowRestrictedLockUtils.class,
|
||||||
|
ShadowDevicePolicyManager.class,
|
||||||
|
ShadowApplicationPackageManager.class,
|
||||||
|
TrustAgentsPreferenceControllerTest.ShadowTrustAgentManager.class
|
||||||
|
})
|
||||||
|
public class TrustAgentsPreferenceControllerTest {
|
||||||
|
|
||||||
|
private static final Intent TEST_INTENT =
|
||||||
|
new Intent(TrustAgentService.SERVICE_INTERFACE);
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private ShadowApplicationPackageManager mPackageManager;
|
||||||
|
private TrustAgentsPreferenceController mController;
|
||||||
|
private PreferenceManager mPreferenceManager;
|
||||||
|
private PreferenceScreen mPreferenceScreen;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mContext = RuntimeEnvironment.application;
|
||||||
|
mPackageManager = (ShadowApplicationPackageManager) Shadows.shadowOf(
|
||||||
|
mContext.getPackageManager());
|
||||||
|
mController = new TrustAgentsPreferenceController(mContext, "pref_key");
|
||||||
|
mPreferenceManager = new PreferenceManager(mContext);
|
||||||
|
mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
|
||||||
|
mPreferenceScreen.setKey("pref_key");
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
ShadowTrustAgentManager.clearPermissionGrantedList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAvailabilityStatus_byDefault_shouldBeShown() {
|
||||||
|
assertThat(mController.getAvailabilityStatus())
|
||||||
|
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStart_noTrustAgent_shouldNotAddPreference() {
|
||||||
|
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||||
|
mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
|
||||||
|
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
mController.onStart();
|
||||||
|
|
||||||
|
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void
|
||||||
|
onStart_hasAUninstalledTrustAgent_shouldRemoveOnePreferenceAndLeaveTwoPreferences() {
|
||||||
|
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||||
|
final ResolveInfo uninstalledTrustAgent = availableAgents.get(0);
|
||||||
|
for (ResolveInfo rInfo : availableAgents) {
|
||||||
|
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
|
||||||
|
}
|
||||||
|
mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
mController.onStart();
|
||||||
|
availableAgents.remove(uninstalledTrustAgent);
|
||||||
|
|
||||||
|
mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
|
||||||
|
mController.onStart();
|
||||||
|
|
||||||
|
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStart_hasANewTrustAgent_shouldAddOnePreferenceAndHaveFourPreferences() {
|
||||||
|
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||||
|
final ComponentName newComponentName = new ComponentName("test.data.packageD", "clzDDD");
|
||||||
|
final ResolveInfo newTrustAgent = createFakeResolveInfo(newComponentName);
|
||||||
|
for (ResolveInfo rInfo : availableAgents) {
|
||||||
|
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
|
||||||
|
}
|
||||||
|
mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
mController.onStart();
|
||||||
|
availableAgents.add(newTrustAgent);
|
||||||
|
ShadowTrustAgentManager.grantPermissionToResolveInfo(newTrustAgent);
|
||||||
|
|
||||||
|
mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
|
||||||
|
mController.onStart();
|
||||||
|
|
||||||
|
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStart_hasUnrestrictedTrustAgent_shouldAddThreeChangeablePreferences() {
|
||||||
|
ShadowRestrictedLockUtils.setKeyguardDisabledFeatures(0);
|
||||||
|
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||||
|
for (ResolveInfo rInfo : availableAgents) {
|
||||||
|
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
|
||||||
|
}
|
||||||
|
mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
|
||||||
|
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
mController.onStart();
|
||||||
|
|
||||||
|
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(3);
|
||||||
|
for (int i = 0; i < mPreferenceScreen.getPreferenceCount(); i++) {
|
||||||
|
RestrictedSwitchPreference preference =
|
||||||
|
(RestrictedSwitchPreference) mPreferenceScreen.getPreference(i);
|
||||||
|
assertThat(preference.isDisabledByAdmin()).isFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStart_hasRestrictedTructAgent_shouldAddThreeUnchangeablePreferences() {
|
||||||
|
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||||
|
for (ResolveInfo rInfo : availableAgents) {
|
||||||
|
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
|
||||||
|
}
|
||||||
|
mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
|
||||||
|
ShadowRestrictedLockUtils.setKeyguardDisabledFeatures(
|
||||||
|
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
|
||||||
|
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
mController.onStart();
|
||||||
|
|
||||||
|
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(3);
|
||||||
|
for (int i = 0; i < mPreferenceScreen.getPreferenceCount(); i++) {
|
||||||
|
RestrictedSwitchPreference preference =
|
||||||
|
(RestrictedSwitchPreference) mPreferenceScreen.getPreference(i);
|
||||||
|
assertThat(preference.isDisabledByAdmin()).isTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ResolveInfo> createFakeAvailableAgents() {
|
||||||
|
final List<ComponentName> componentNames = new ArrayList<>();
|
||||||
|
componentNames.add(new ComponentName("test.data.packageA", "clzAAA"));
|
||||||
|
componentNames.add(new ComponentName("test.data.packageB", "clzBBB"));
|
||||||
|
componentNames.add(new ComponentName("test.data.packageC", "clzCCC"));
|
||||||
|
final List<ResolveInfo> result = new ArrayList<>();
|
||||||
|
for (ComponentName cn : componentNames) {
|
||||||
|
final ResolveInfo ri = createFakeResolveInfo(cn);
|
||||||
|
result.add(ri);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResolveInfo createFakeResolveInfo(ComponentName cn) {
|
||||||
|
final ResolveInfo ri = new ResolveInfo();
|
||||||
|
ri.serviceInfo = new ServiceInfo();
|
||||||
|
ri.serviceInfo.packageName = cn.getPackageName();
|
||||||
|
ri.serviceInfo.name = cn.getClassName();
|
||||||
|
ri.serviceInfo.applicationInfo = new ApplicationInfo();
|
||||||
|
ri.serviceInfo.applicationInfo.packageName = cn.getPackageName();
|
||||||
|
ri.serviceInfo.applicationInfo.name = cn.getClassName();
|
||||||
|
return ri;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Implements(TrustAgentManager.class)
|
||||||
|
public static class ShadowTrustAgentManager {
|
||||||
|
private final static List<ResolveInfo> sPermissionGrantedList = new ArrayList<>();
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
public boolean shouldProvideTrust(ResolveInfo resolveInfo, PackageManager pm) {
|
||||||
|
if (sPermissionGrantedList.contains(resolveInfo)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void grantPermissionToResolveInfo(ResolveInfo rInfo) {
|
||||||
|
sPermissionGrantedList.add(rInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearPermissionGrantedList() {
|
||||||
|
sPermissionGrantedList.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -5,6 +5,7 @@ import android.annotation.Nullable;
|
|||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Implementation;
|
import org.robolectric.annotation.Implementation;
|
||||||
@@ -12,6 +13,7 @@ import org.robolectric.annotation.Implements;
|
|||||||
import org.robolectric.shadow.api.Shadow;
|
import org.robolectric.shadow.api.Shadow;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -75,4 +77,10 @@ public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDev
|
|||||||
return (ShadowDevicePolicyManager) Shadow.extract(
|
return (ShadowDevicePolicyManager) Shadow.extract(
|
||||||
RuntimeEnvironment.application.getSystemService(DevicePolicyManager.class));
|
RuntimeEnvironment.application.getSystemService(DevicePolicyManager.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable
|
||||||
|
List<PersistableBundle> getTrustAgentConfiguration(
|
||||||
|
@Nullable ComponentName admin, @NonNull ComponentName agent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,12 +17,15 @@
|
|||||||
package com.android.settings.testutils.shadow;
|
package com.android.settings.testutils.shadow;
|
||||||
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
|
|
||||||
import org.robolectric.annotation.Implementation;
|
import org.robolectric.annotation.Implementation;
|
||||||
import org.robolectric.annotation.Implements;
|
import org.robolectric.annotation.Implements;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Implements(LockPatternUtils.class)
|
@Implements(LockPatternUtils.class)
|
||||||
public class ShadowLockPatternUtils {
|
public class ShadowLockPatternUtils {
|
||||||
|
|
||||||
@@ -49,6 +52,11 @@ public class ShadowLockPatternUtils {
|
|||||||
return sDeviceEncryptionEnabled;
|
return sDeviceEncryptionEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
public List<ComponentName> getEnabledTrustAgents(int userId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static void setDeviceEncryptionEnabled(boolean deviceEncryptionEnabled) {
|
public static void setDeviceEncryptionEnabled(boolean deviceEncryptionEnabled) {
|
||||||
sDeviceEncryptionEnabled = deviceEncryptionEnabled;
|
sDeviceEncryptionEnabled = deviceEncryptionEnabled;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user