/* * Copyright (C) 2014 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; 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.Bundle; import android.os.UserHandle; import android.service.trust.TrustAgentService; import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceGroup; import android.util.ArrayMap; import android.util.ArraySet; import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.internal.widget.LockPatternUtils; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedSwitchPreference; import java.util.List; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; public class TrustAgentSettings extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener { private static final String SERVICE_INTERFACE = TrustAgentService.SERVICE_INTERFACE; private ArrayMap<ComponentName, AgentInfo> mAvailableAgents; private final ArraySet<ComponentName> mActiveAgents = new ArraySet<ComponentName>(); private LockPatternUtils mLockPatternUtils; private DevicePolicyManager mDpm; 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 protected int getMetricsCategory() { return MetricsEvent.TRUST_AGENT; } @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); mDpm = getActivity().getSystemService(DevicePolicyManager.class); 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()); } 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 (!TrustAgentUtils.checkProvidePermission(resolveInfo, pm)) continue; ComponentName name = TrustAgentUtils.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 public boolean onPreferenceChange(Preference preference, Object newValue) { if (preference instanceof SwitchPreference) { 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; } }