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