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; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ResolveInfo; 25 import android.graphics.drawable.Drawable; 26 import android.os.Bundle; 27 import android.os.UserHandle; 28 import android.service.trust.TrustAgentService; 29 import android.support.v14.preference.SwitchPreference; 30 import android.support.v7.preference.Preference; 31 import android.support.v7.preference.PreferenceGroup; 32 import android.util.ArrayMap; 33 import android.util.ArraySet; 34 35 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 36 import com.android.internal.widget.LockPatternUtils; 37 import com.android.settings.overlay.FeatureFactory; 38 import com.android.settings.trustagent.TrustAgentManager; 39 import com.android.settingslib.RestrictedLockUtils; 40 import com.android.settingslib.RestrictedSwitchPreference; 41 42 import java.util.List; 43 44 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 45 46 public class TrustAgentSettings extends SettingsPreferenceFragment implements 47 Preference.OnPreferenceChangeListener { 48 private static final String SERVICE_INTERFACE = TrustAgentService.SERVICE_INTERFACE; 49 50 private ArrayMap<ComponentName, AgentInfo> mAvailableAgents; 51 private final ArraySet<ComponentName> mActiveAgents = new ArraySet<ComponentName>(); 52 private LockPatternUtils mLockPatternUtils; 53 private DevicePolicyManager mDpm; 54 private TrustAgentManager mTrustAgentManager; 55 56 public static final class AgentInfo { 57 CharSequence label; 58 ComponentName component; // service that implements ITrustAgent 59 SwitchPreference preference; 60 public Drawable icon; 61 62 @Override 63 public boolean equals(Object other) { 64 if (other instanceof AgentInfo) { 65 return component.equals(((AgentInfo)other).component); 66 } 67 return true; 68 } 69 70 public int compareTo(AgentInfo other) { 71 return component.compareTo(other.component); 72 } 73 } 74 75 @Override 76 public int getMetricsCategory() { 77 return MetricsEvent.TRUST_AGENT; 78 } 79 80 @Override 81 protected int getHelpResource() { 82 return R.string.help_url_trust_agent; 83 } 84 85 @Override 86 public void onCreate(Bundle icicle) { 87 super.onCreate(icicle); 88 mDpm = getActivity().getSystemService(DevicePolicyManager.class); 89 mTrustAgentManager = 90 FeatureFactory.getFactory(getActivity()).getSecurityFeatureProvider() 91 .getTrustAgentManager(); 92 93 addPreferencesFromResource(R.xml.trust_agent_settings); 94 } 95 96 public void onResume() { 97 super.onResume(); 98 removePreference("dummy_preference"); 99 updateAgents(); 100 }; 101 102 private void updateAgents() { 103 final Context context = getActivity(); 104 if (mAvailableAgents == null) { 105 mAvailableAgents = findAvailableTrustAgents(); 106 } 107 if (mLockPatternUtils == null) { 108 mLockPatternUtils = new LockPatternUtils(getActivity()); 109 } 110 loadActiveAgents(); 111 PreferenceGroup category = 112 (PreferenceGroup) getPreferenceScreen().findPreference("trust_agents"); 113 category.removeAll(); 114 115 final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(context, 116 DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId()); 117 118 final int count = mAvailableAgents.size(); 119 for (int i = 0; i < count; i++) { 120 AgentInfo agent = mAvailableAgents.valueAt(i); 121 final RestrictedSwitchPreference preference = 122 new RestrictedSwitchPreference(getPrefContext()); 123 preference.useAdminDisabledSummary(true); 124 agent.preference = preference; 125 preference.setPersistent(false); 126 preference.setTitle(agent.label); 127 preference.setIcon(agent.icon); 128 preference.setPersistent(false); 129 preference.setOnPreferenceChangeListener(this); 130 preference.setChecked(mActiveAgents.contains(agent.component)); 131 132 if (admin != null 133 && mDpm.getTrustAgentConfiguration(null, agent.component) == null) { 134 preference.setChecked(false); 135 preference.setDisabledByAdmin(admin); 136 } 137 138 category.addPreference(agent.preference); 139 } 140 } 141 142 private void loadActiveAgents() { 143 List<ComponentName> activeTrustAgents = mLockPatternUtils.getEnabledTrustAgents( 144 UserHandle.myUserId()); 145 if (activeTrustAgents != null) { 146 mActiveAgents.addAll(activeTrustAgents); 147 } 148 } 149 150 private void saveActiveAgents() { 151 mLockPatternUtils.setEnabledTrustAgents(mActiveAgents, 152 UserHandle.myUserId()); 153 } 154 155 ArrayMap<ComponentName, AgentInfo> findAvailableTrustAgents() { 156 PackageManager pm = getActivity().getPackageManager(); 157 Intent trustAgentIntent = new Intent(SERVICE_INTERFACE); 158 List<ResolveInfo> resolveInfos = pm.queryIntentServices(trustAgentIntent, 159 PackageManager.GET_META_DATA); 160 161 ArrayMap<ComponentName, AgentInfo> agents = new ArrayMap<ComponentName, AgentInfo>(); 162 final int count = resolveInfos.size(); 163 agents.ensureCapacity(count); 164 for (int i = 0; i < count; i++ ) { 165 ResolveInfo resolveInfo = resolveInfos.get(i); 166 if (resolveInfo.serviceInfo == null) { 167 continue; 168 } 169 if (!mTrustAgentManager.shouldProvideTrust(resolveInfo, pm)) { 170 continue; 171 } 172 ComponentName name = TrustAgentUtils.getComponentName(resolveInfo); 173 AgentInfo agentInfo = new AgentInfo(); 174 agentInfo.label = resolveInfo.loadLabel(pm); 175 agentInfo.icon = resolveInfo.loadIcon(pm); 176 agentInfo.component = name; 177 agents.put(name, agentInfo); 178 } 179 return agents; 180 } 181 182 @Override 183 public boolean onPreferenceChange(Preference preference, Object newValue) { 184 if (preference instanceof SwitchPreference) { 185 final int count = mAvailableAgents.size(); 186 for (int i = 0; i < count; i++) { 187 AgentInfo agent = mAvailableAgents.valueAt(i); 188 if (agent.preference == preference) { 189 if ((Boolean) newValue) { 190 if (!mActiveAgents.contains(agent.component)) { 191 mActiveAgents.add(agent.component); 192 } 193 } else { 194 mActiveAgents.remove(agent.component); 195 } 196 saveActiveAgents(); 197 return true; 198 } 199 } 200 } 201 return false; 202 } 203 204 } 205