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