15a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller/* 25a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * Copyright (C) 2014 The Android Open Source Project 35a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * 45a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 55a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * you may not use this file except in compliance with the License. 65a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * You may obtain a copy of the License at 75a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * 85a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * http://www.apache.org/licenses/LICENSE-2.0 95a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * 105a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * Unless required by applicable law or agreed to in writing, software 115a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * distributed under the License is distributed on an "AS IS" BASIS, 125a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * See the License for the specific language governing permissions and 145a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller * limitations under the License. 155a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller */ 165a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 175a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerpackage com.android.settings; 185a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 19088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roosimport android.app.admin.DevicePolicyManager; 205a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.content.ComponentName; 215a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.content.Context; 225a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.content.Intent; 235a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.content.pm.PackageManager; 245a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.content.pm.ResolveInfo; 255a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.graphics.drawable.Drawable; 265a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.os.Bundle; 275437588abd69bf3eff59684528aaf50e09b6cffcAdrian Roosimport android.os.UserHandle; 285a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.service.trust.TrustAgentService; 2939b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v14.preference.SwitchPreference; 3039b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference; 3139b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceGroup; 325a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.util.ArrayMap; 335a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport android.util.ArraySet; 345a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 359d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wrenimport com.android.internal.logging.MetricsProto.MetricsEvent; 365a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerimport com.android.internal.widget.LockPatternUtils; 37ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shankaimport com.android.settingslib.RestrictedLockUtils; 38ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shankaimport com.android.settingslib.RestrictedSwitchPreference; 395a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 4039b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport java.util.List; 4139b467482d1bf256a111c757e9b7621c6f523271Jason Monk 42ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shankaimport static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 43ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shanka 445a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Millerpublic class TrustAgentSettings extends SettingsPreferenceFragment implements 455a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller Preference.OnPreferenceChangeListener { 465a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller private static final String SERVICE_INTERFACE = TrustAgentService.SERVICE_INTERFACE; 47088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roos 485a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller private ArrayMap<ComponentName, AgentInfo> mAvailableAgents; 495a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller private final ArraySet<ComponentName> mActiveAgents = new ArraySet<ComponentName>(); 505a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller private LockPatternUtils mLockPatternUtils; 51088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roos private DevicePolicyManager mDpm; 525a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 535a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller public static final class AgentInfo { 545a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller CharSequence label; 555a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller ComponentName component; // service that implements ITrustAgent 565a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller SwitchPreference preference; 575a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller public Drawable icon; 585a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 595a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller @Override 605a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller public boolean equals(Object other) { 615a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if (other instanceof AgentInfo) { 625a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller return component.equals(((AgentInfo)other).component); 635a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 645a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller return true; 655a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 665a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 675a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller public int compareTo(AgentInfo other) { 685a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller return component.compareTo(other.component); 695a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 705a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 715a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 725a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller @Override 738a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren protected int getMetricsCategory() { 749d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wren return MetricsEvent.TRUST_AGENT; 758a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren } 768a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren 778a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren @Override 785a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller public void onCreate(Bundle icicle) { 795a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller super.onCreate(icicle); 80088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roos mDpm = getActivity().getSystemService(DevicePolicyManager.class); 815a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller addPreferencesFromResource(R.xml.trust_agent_settings); 825a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 835a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 845a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller public void onResume() { 855a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller super.onResume(); 86ba59f5b222190f423d20298e0328ec3f8c1c45cdAdrian Roos removePreference("dummy_preference"); 875a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller updateAgents(); 885a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller }; 895a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 905a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller private void updateAgents() { 915a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller final Context context = getActivity(); 925a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if (mAvailableAgents == null) { 935a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller mAvailableAgents = findAvailableTrustAgents(); 945a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 955a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if (mLockPatternUtils == null) { 965a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller mLockPatternUtils = new LockPatternUtils(getActivity()); 975a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 985a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller loadActiveAgents(); 995a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller PreferenceGroup category = 1005a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller (PreferenceGroup) getPreferenceScreen().findPreference("trust_agents"); 1015a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller category.removeAll(); 102088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roos 103ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shanka final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(context, 104ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shanka DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId()); 105088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roos 1065a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller final int count = mAvailableAgents.size(); 1075a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller for (int i = 0; i < count; i++) { 1085a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller AgentInfo agent = mAvailableAgents.valueAt(i); 109ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shanka final RestrictedSwitchPreference preference = 110ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shanka new RestrictedSwitchPreference(getPrefContext()); 111ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shanka preference.useAdminDisabledSummary(true); 1125a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller agent.preference = preference; 1135a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller preference.setPersistent(false); 1145a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller preference.setTitle(agent.label); 1155a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller preference.setIcon(agent.icon); 1165a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller preference.setPersistent(false); 1175a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller preference.setOnPreferenceChangeListener(this); 1185a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller preference.setChecked(mActiveAgents.contains(agent.component)); 119088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roos 120ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shanka if (admin != null 121088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roos && mDpm.getTrustAgentConfiguration(null, agent.component) == null) { 1229854dfaf1d6a001d41538598a1ae3322d112ec9bKenny Guy preference.setChecked(false); 123ec1052dbadbc472c0afff943a9b61e6d95ab8089Sudheer Shanka preference.setDisabledByAdmin(admin); 124088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roos } 125088de47aa8595f9e4142ce0fe6885840b83edc93Adrian Roos 1265a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller category.addPreference(agent.preference); 1275a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1285a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1295a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 1305a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller private void loadActiveAgents() { 1315437588abd69bf3eff59684528aaf50e09b6cffcAdrian Roos List<ComponentName> activeTrustAgents = mLockPatternUtils.getEnabledTrustAgents( 1325437588abd69bf3eff59684528aaf50e09b6cffcAdrian Roos UserHandle.myUserId()); 1335a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if (activeTrustAgents != null) { 1345a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller mActiveAgents.addAll(activeTrustAgents); 1355a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1365a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1375a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 1385a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller private void saveActiveAgents() { 1395437588abd69bf3eff59684528aaf50e09b6cffcAdrian Roos mLockPatternUtils.setEnabledTrustAgents(mActiveAgents, 1405437588abd69bf3eff59684528aaf50e09b6cffcAdrian Roos UserHandle.myUserId()); 1415a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1425a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 1435a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller ArrayMap<ComponentName, AgentInfo> findAvailableTrustAgents() { 1445a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller PackageManager pm = getActivity().getPackageManager(); 1455a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller Intent trustAgentIntent = new Intent(SERVICE_INTERFACE); 1465a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller List<ResolveInfo> resolveInfos = pm.queryIntentServices(trustAgentIntent, 1475a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller PackageManager.GET_META_DATA); 1485a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 1495a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller ArrayMap<ComponentName, AgentInfo> agents = new ArrayMap<ComponentName, AgentInfo>(); 1505a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller final int count = resolveInfos.size(); 1515a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller agents.ensureCapacity(count); 1525a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller for (int i = 0; i < count; i++ ) { 1535a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller ResolveInfo resolveInfo = resolveInfos.get(i); 1545a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if (resolveInfo.serviceInfo == null) continue; 1555a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if (!TrustAgentUtils.checkProvidePermission(resolveInfo, pm)) continue; 1565a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller ComponentName name = TrustAgentUtils.getComponentName(resolveInfo); 1575a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller AgentInfo agentInfo = new AgentInfo(); 1585a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller agentInfo.label = resolveInfo.loadLabel(pm); 1595a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller agentInfo.icon = resolveInfo.loadIcon(pm); 1605a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller agentInfo.component = name; 1615a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller agents.put(name, agentInfo); 1625a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1635a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller return agents; 1645a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1655a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 1665a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller @Override 1675a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller public boolean onPreferenceChange(Preference preference, Object newValue) { 1685a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if (preference instanceof SwitchPreference) { 1695a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller final int count = mAvailableAgents.size(); 1705a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller for (int i = 0; i < count; i++) { 1715a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller AgentInfo agent = mAvailableAgents.valueAt(i); 1725a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if (agent.preference == preference) { 1735a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if ((Boolean) newValue) { 1745a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller if (!mActiveAgents.contains(agent.component)) { 1755a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller mActiveAgents.add(agent.component); 1765a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1775a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } else { 1785a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller mActiveAgents.remove(agent.component); 1795a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1805a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller saveActiveAgents(); 1815a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller return true; 1825a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1835a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1845a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1855a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller return false; 1865a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller } 1875a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller 1885a10a8df0efcf034077cbfcd28dd2e495b8d0441Jim Miller} 189