1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.security.trustagent; 18 19 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 20 21 import android.app.admin.DevicePolicyManager; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.pm.PackageManager; 26 import android.content.pm.ResolveInfo; 27 import android.graphics.drawable.Drawable; 28 import android.os.Bundle; 29 import android.os.UserHandle; 30 import android.service.trust.TrustAgentService; 31 import android.support.v14.preference.SwitchPreference; 32 import android.support.v7.preference.Preference; 33 import android.support.v7.preference.PreferenceGroup; 34 import android.util.ArrayMap; 35 import android.util.ArraySet; 36 37 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 38 import com.android.internal.widget.LockPatternUtils; 39 import com.android.settings.R; 40 import com.android.settings.SettingsPreferenceFragment; 41 import com.android.settings.overlay.FeatureFactory; 42 import com.android.settingslib.RestrictedLockUtils; 43 import com.android.settingslib.RestrictedSwitchPreference; 44 45 import java.util.List; 46 47 public class TrustAgentSettings extends SettingsPreferenceFragment implements 48 Preference.OnPreferenceChangeListener { 49 private static final String SERVICE_INTERFACE = TrustAgentService.SERVICE_INTERFACE; 50 51 private ArrayMap<ComponentName, AgentInfo> mAvailableAgents; 52 private final ArraySet<ComponentName> mActiveAgents = new ArraySet<ComponentName>(); 53 private LockPatternUtils mLockPatternUtils; 54 private DevicePolicyManager mDpm; 55 private TrustAgentManager mTrustAgentManager; 56 57 public static final class AgentInfo { 58 CharSequence label; 59 ComponentName component; // service that implements ITrustAgent 60 SwitchPreference preference; 61 public Drawable icon; 62 63 @Override 64 public boolean equals(Object other) { 65 if (other instanceof AgentInfo) { 66 return component.equals(((AgentInfo)other).component); 67 } 68 return true; 69 } 70 71 public int compareTo(AgentInfo other) { 72 return component.compareTo(other.component); 73 } 74 } 75 76 @Override 77 public int getMetricsCategory() { 78 return MetricsEvent.TRUST_AGENT; 79 } 80 81 @Override 82 public int getHelpResource() { 83 return R.string.help_url_trust_agent; 84 } 85 86 @Override 87 public void onCreate(Bundle icicle) { 88 super.onCreate(icicle); 89 mDpm = getActivity().getSystemService(DevicePolicyManager.class); 90 mTrustAgentManager = 91 FeatureFactory.getFactory(getActivity()).getSecurityFeatureProvider() 92 .getTrustAgentManager(); 93 94 addPreferencesFromResource(R.xml.trust_agent_settings); 95 } 96 97 public void onResume() { 98 super.onResume(); 99 removePreference("dummy_preference"); 100 updateAgents(); 101 } 102 103 private void updateAgents() { 104 final Context context = getActivity(); 105 if (mAvailableAgents == null) { 106 mAvailableAgents = findAvailableTrustAgents(); 107 } 108 if (mLockPatternUtils == null) { 109 mLockPatternUtils = new LockPatternUtils(getActivity()); 110 } 111 loadActiveAgents(); 112 PreferenceGroup category = 113 (PreferenceGroup) getPreferenceScreen().findPreference("trust_agents"); 114 category.removeAll(); 115 116 final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(context, 117 DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId()); 118 119 final int count = mAvailableAgents.size(); 120 for (int i = 0; i < count; i++) { 121 AgentInfo agent = mAvailableAgents.valueAt(i); 122 final RestrictedSwitchPreference preference = 123 new RestrictedSwitchPreference(getPrefContext()); 124 preference.useAdminDisabledSummary(true); 125 agent.preference = preference; 126 preference.setPersistent(false); 127 preference.setTitle(agent.label); 128 preference.setIcon(agent.icon); 129 preference.setPersistent(false); 130 preference.setOnPreferenceChangeListener(this); 131 preference.setChecked(mActiveAgents.contains(agent.component)); 132 133 if (admin != null 134 && mDpm.getTrustAgentConfiguration(null, agent.component) == null) { 135 preference.setChecked(false); 136 preference.setDisabledByAdmin(admin); 137 } 138 139 category.addPreference(agent.preference); 140 } 141 } 142 143 private void loadActiveAgents() { 144 List<ComponentName> activeTrustAgents = mLockPatternUtils.getEnabledTrustAgents( 145 UserHandle.myUserId()); 146 if (activeTrustAgents != null) { 147 mActiveAgents.addAll(activeTrustAgents); 148 } 149 } 150 151 private void saveActiveAgents() { 152 mLockPatternUtils.setEnabledTrustAgents(mActiveAgents, 153 UserHandle.myUserId()); 154 } 155 156 private ArrayMap<ComponentName, AgentInfo> findAvailableTrustAgents() { 157 PackageManager pm = getActivity().getPackageManager(); 158 Intent trustAgentIntent = new Intent(SERVICE_INTERFACE); 159 List<ResolveInfo> resolveInfos = pm.queryIntentServices(trustAgentIntent, 160 PackageManager.GET_META_DATA); 161 162 ArrayMap<ComponentName, AgentInfo> agents = new ArrayMap<ComponentName, AgentInfo>(); 163 final int count = resolveInfos.size(); 164 agents.ensureCapacity(count); 165 for (int i = 0; i < count; i++ ) { 166 ResolveInfo resolveInfo = resolveInfos.get(i); 167 if (resolveInfo.serviceInfo == null) { 168 continue; 169 } 170 if (!mTrustAgentManager.shouldProvideTrust(resolveInfo, pm)) { 171 continue; 172 } 173 ComponentName name = mTrustAgentManager.getComponentName(resolveInfo); 174 AgentInfo agentInfo = new AgentInfo(); 175 agentInfo.label = resolveInfo.loadLabel(pm); 176 agentInfo.icon = resolveInfo.loadIcon(pm); 177 agentInfo.component = name; 178 agents.put(name, agentInfo); 179 } 180 return agents; 181 } 182 183 @Override 184 public boolean onPreferenceChange(Preference preference, Object newValue) { 185 if (preference instanceof SwitchPreference) { 186 final int count = mAvailableAgents.size(); 187 for (int i = 0; i < count; i++) { 188 AgentInfo agent = mAvailableAgents.valueAt(i); 189 if (agent.preference == preference) { 190 if ((Boolean) newValue) { 191 if (!mActiveAgents.contains(agent.component)) { 192 mActiveAgents.add(agent.component); 193 } 194 } else { 195 mActiveAgents.remove(agent.component); 196 } 197 saveActiveAgents(); 198 return true; 199 } 200 } 201 } 202 return false; 203 } 204 205 } 206