TrustManagerService.java revision e681c27dc62006358102a250b46726b7a88efe06
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
17package com.android.server.trust;
18
19import com.android.internal.content.PackageMonitor;
20import com.android.internal.widget.LockPatternUtils;
21import com.android.server.SystemService;
22
23import org.xmlpull.v1.XmlPullParser;
24import org.xmlpull.v1.XmlPullParserException;
25
26import android.Manifest;
27import android.app.ActivityManagerNative;
28import android.app.admin.DevicePolicyManager;
29import android.app.trust.ITrustListener;
30import android.app.trust.ITrustManager;
31import android.content.BroadcastReceiver;
32import android.content.ComponentName;
33import android.content.Context;
34import android.content.Intent;
35import android.content.IntentFilter;
36import android.content.pm.PackageManager;
37import android.content.pm.ResolveInfo;
38import android.content.pm.UserInfo;
39import android.content.res.Resources;
40import android.content.res.TypedArray;
41import android.content.res.XmlResourceParser;
42import android.graphics.drawable.Drawable;
43import android.os.DeadObjectException;
44import android.os.Handler;
45import android.os.IBinder;
46import android.os.Message;
47import android.os.RemoteException;
48import android.os.SystemClock;
49import android.os.UserHandle;
50import android.os.UserManager;
51import android.service.trust.TrustAgentService;
52import android.util.ArraySet;
53import android.util.AttributeSet;
54import android.util.Log;
55import android.util.Slog;
56import android.util.SparseBooleanArray;
57import android.util.Xml;
58
59import java.io.FileDescriptor;
60import java.io.IOException;
61import java.io.PrintWriter;
62import java.util.ArrayList;
63import java.util.List;
64
65/**
66 * Manages trust agents and trust listeners.
67 *
68 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
69 * of each user and notifies them about events that are relevant to them.
70 * It start and stops them based on the value of
71 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
72 *
73 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
74 * trust state changes for any user.
75 *
76 * Trust state and the setting of enabled agents is kept per user and each user has its own
77 * instance of a {@link android.service.trust.TrustAgentService}.
78 */
79public class TrustManagerService extends SystemService {
80
81    private static final boolean DEBUG = false;
82    private static final String TAG = "TrustManagerService";
83
84    private static final Intent TRUST_AGENT_INTENT =
85            new Intent(TrustAgentService.SERVICE_INTERFACE);
86    private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
87
88    private static final int MSG_REGISTER_LISTENER = 1;
89    private static final int MSG_UNREGISTER_LISTENER = 2;
90    private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
91    private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
92    private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5;
93
94    private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>();
95    private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>();
96    private final Receiver mReceiver = new Receiver();
97    private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
98    /* package */ final TrustArchive mArchive = new TrustArchive();
99    private final Context mContext;
100
101    private UserManager mUserManager;
102
103    public TrustManagerService(Context context) {
104        super(context);
105        mContext = context;
106        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
107    }
108
109    @Override
110    public void onStart() {
111        publishBinderService(Context.TRUST_SERVICE, mService);
112    }
113
114    @Override
115    public void onBootPhase(int phase) {
116        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && !isSafeMode()) {
117            mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
118            mReceiver.register(mContext);
119            refreshAgentList(UserHandle.USER_ALL);
120        }
121    }
122
123    // Agent management
124
125    private static final class AgentInfo {
126        CharSequence label;
127        Drawable icon;
128        ComponentName component; // service that implements ITrustAgent
129        ComponentName settings; // setting to launch to modify agent.
130        TrustAgentWrapper agent;
131        int userId;
132
133        @Override
134        public boolean equals(Object other) {
135            if (!(other instanceof AgentInfo)) {
136                return false;
137            }
138            AgentInfo o = (AgentInfo) other;
139            return component.equals(o.component) && userId == o.userId;
140        }
141
142        @Override
143        public int hashCode() {
144            return component.hashCode() * 31 + userId;
145        }
146    }
147
148    private void updateTrustAll() {
149        List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
150        for (UserInfo userInfo : userInfos) {
151            updateTrust(userInfo.id, false);
152        }
153    }
154
155    public void updateTrust(int userId, boolean initiatedByUser) {
156        dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
157        dispatchOnTrustChanged(aggregateIsTrusted(userId), userId, initiatedByUser);
158    }
159
160    void refreshAgentList(int userId) {
161        if (DEBUG) Slog.d(TAG, "refreshAgentList()");
162        if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) {
163            Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle,"
164                    + " must be USER_ALL or a specific user.", new Throwable("here"));
165            userId = UserHandle.USER_ALL;
166        }
167        PackageManager pm = mContext.getPackageManager();
168
169        List<UserInfo> userInfos;
170        if (userId == UserHandle.USER_ALL) {
171            userInfos = mUserManager.getUsers(true /* excludeDying */);
172        } else {
173            userInfos = new ArrayList<>();
174            userInfos.add(mUserManager.getUserInfo(userId));
175        }
176        LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
177
178        ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
179        obsoleteAgents.addAll(mActiveAgents);
180
181        for (UserInfo userInfo : userInfos) {
182            if (lockPatternUtils.getKeyguardStoredPasswordQuality(userInfo.id)
183                    == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) continue;
184            if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue;
185            DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
186            int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
187            final boolean disableTrustAgents =
188                    (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
189
190            List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
191            if (enabledAgents == null) {
192                continue;
193            }
194            List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
195                    PackageManager.GET_META_DATA, userInfo.id);
196            for (ResolveInfo resolveInfo : resolveInfos) {
197                if (resolveInfo.serviceInfo == null) continue;
198
199                String packageName = resolveInfo.serviceInfo.packageName;
200                if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
201                        != PackageManager.PERMISSION_GRANTED) {
202                    Log.w(TAG, "Skipping agent because package " + packageName
203                            + " does not have permission " + PERMISSION_PROVIDE_AGENT + ".");
204                    continue;
205                }
206
207                ComponentName name = getComponentName(resolveInfo);
208                if (!enabledAgents.contains(name)) continue;
209
210                if (disableTrustAgents) {
211                    List<String> features =
212                            dpm.getTrustAgentFeaturesEnabled(null /* admin */, name);
213                    // Disable agent if no features are enabled.
214                    if (features == null || features.isEmpty()) continue;
215                }
216
217                AgentInfo agentInfo = new AgentInfo();
218                agentInfo.component = name;
219                agentInfo.userId = userInfo.id;
220                if (!mActiveAgents.contains(agentInfo)) {
221                    agentInfo.label = resolveInfo.loadLabel(pm);
222                    agentInfo.icon = resolveInfo.loadIcon(pm);
223                    agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
224                    agentInfo.agent = new TrustAgentWrapper(mContext, this,
225                            new Intent().setComponent(name), userInfo.getUserHandle());
226                    mActiveAgents.add(agentInfo);
227                } else {
228                    obsoleteAgents.remove(agentInfo);
229                }
230            }
231        }
232
233        boolean trustMayHaveChanged = false;
234        for (int i = 0; i < obsoleteAgents.size(); i++) {
235            AgentInfo info = obsoleteAgents.valueAt(i);
236            if (userId == UserHandle.USER_ALL || userId == info.userId) {
237                if (info.agent.isManagingTrust()) {
238                    trustMayHaveChanged = true;
239                }
240                info.agent.unbind();
241                mActiveAgents.remove(info);
242            }
243        }
244
245        if (trustMayHaveChanged) {
246            updateTrustAll();
247        }
248    }
249
250    void updateDevicePolicyFeatures() {
251        for (int i = 0; i < mActiveAgents.size(); i++) {
252            AgentInfo info = mActiveAgents.valueAt(i);
253            if (info.agent.isConnected()) {
254                info.agent.updateDevicePolicyFeatures();
255            }
256        }
257    }
258
259    private void removeAgentsOfPackage(String packageName) {
260        boolean trustMayHaveChanged = false;
261        for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
262            AgentInfo info = mActiveAgents.valueAt(i);
263            if (packageName.equals(info.component.getPackageName())) {
264                Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
265                if (info.agent.isManagingTrust()) {
266                    trustMayHaveChanged = true;
267                }
268                info.agent.unbind();
269                mActiveAgents.removeAt(i);
270            }
271        }
272        if (trustMayHaveChanged) {
273            updateTrustAll();
274        }
275    }
276
277    public void resetAgent(ComponentName name, int userId) {
278        boolean trustMayHaveChanged = false;
279        for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
280            AgentInfo info = mActiveAgents.valueAt(i);
281            if (name.equals(info.component) && userId == info.userId) {
282                Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
283                if (info.agent.isManagingTrust()) {
284                    trustMayHaveChanged = true;
285                }
286                info.agent.unbind();
287                mActiveAgents.removeAt(i);
288            }
289        }
290        if (trustMayHaveChanged) {
291            updateTrust(userId, false);
292        }
293        refreshAgentList(userId);
294    }
295
296    private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
297        if (resolveInfo == null || resolveInfo.serviceInfo == null
298                || resolveInfo.serviceInfo.metaData == null) return null;
299        String cn = null;
300        XmlResourceParser parser = null;
301        Exception caughtException = null;
302        try {
303            parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
304                    TrustAgentService.TRUST_AGENT_META_DATA);
305            if (parser == null) {
306                Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
307                return null;
308            }
309            Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
310            AttributeSet attrs = Xml.asAttributeSet(parser);
311            int type;
312            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
313                    && type != XmlPullParser.START_TAG) {
314                // Drain preamble.
315            }
316            String nodeName = parser.getName();
317            if (!"trust-agent".equals(nodeName)) {
318                Slog.w(TAG, "Meta-data does not start with trust-agent tag");
319                return null;
320            }
321            TypedArray sa = res
322                    .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
323            cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
324            sa.recycle();
325        } catch (PackageManager.NameNotFoundException e) {
326            caughtException = e;
327        } catch (IOException e) {
328            caughtException = e;
329        } catch (XmlPullParserException e) {
330            caughtException = e;
331        } finally {
332            if (parser != null) parser.close();
333        }
334        if (caughtException != null) {
335            Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
336            return null;
337        }
338        if (cn == null) {
339            return null;
340        }
341        if (cn.indexOf('/') < 0) {
342            cn = resolveInfo.serviceInfo.packageName + "/" + cn;
343        }
344        return ComponentName.unflattenFromString(cn);
345    }
346
347    private ComponentName getComponentName(ResolveInfo resolveInfo) {
348        if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
349        return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
350    }
351
352    // Agent dispatch and aggregation
353
354    private boolean aggregateIsTrusted(int userId) {
355        if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
356            return false;
357        }
358        for (int i = 0; i < mActiveAgents.size(); i++) {
359            AgentInfo info = mActiveAgents.valueAt(i);
360            if (info.userId == userId) {
361                if (info.agent.isTrusted()) {
362                    return true;
363                }
364            }
365        }
366        return false;
367    }
368
369    private boolean aggregateIsTrustManaged(int userId) {
370        if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
371            return false;
372        }
373        for (int i = 0; i < mActiveAgents.size(); i++) {
374            AgentInfo info = mActiveAgents.valueAt(i);
375            if (info.userId == userId) {
376                if (info.agent.isManagingTrust()) {
377                    return true;
378                }
379            }
380        }
381        return false;
382    }
383
384    private void dispatchUnlockAttempt(boolean successful, int userId) {
385        for (int i = 0; i < mActiveAgents.size(); i++) {
386            AgentInfo info = mActiveAgents.valueAt(i);
387            if (info.userId == userId) {
388                info.agent.onUnlockAttempt(successful);
389            }
390        }
391
392        if (successful) {
393            updateUserHasAuthenticated(userId);
394        }
395    }
396
397    private void updateUserHasAuthenticated(int userId) {
398        if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
399            mUserHasAuthenticatedSinceBoot.put(userId, true);
400            refreshAgentList(userId);
401        }
402    }
403
404
405    private void requireCredentialEntry(int userId) {
406        if (userId == UserHandle.USER_ALL) {
407            mUserHasAuthenticatedSinceBoot.clear();
408            refreshAgentList(UserHandle.USER_ALL);
409        } else {
410            mUserHasAuthenticatedSinceBoot.put(userId, false);
411            refreshAgentList(userId);
412        }
413    }
414
415    // Listeners
416
417    private void addListener(ITrustListener listener) {
418        for (int i = 0; i < mTrustListeners.size(); i++) {
419            if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
420                return;
421            }
422        }
423        mTrustListeners.add(listener);
424    }
425
426    private void removeListener(ITrustListener listener) {
427        for (int i = 0; i < mTrustListeners.size(); i++) {
428            if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
429                mTrustListeners.remove(i);
430                return;
431            }
432        }
433    }
434
435    private void dispatchOnTrustChanged(boolean enabled, int userId, boolean initiatedByUser) {
436        if (!enabled) initiatedByUser = false;
437        for (int i = 0; i < mTrustListeners.size(); i++) {
438            try {
439                mTrustListeners.get(i).onTrustChanged(enabled, userId, initiatedByUser);
440            } catch (DeadObjectException e) {
441                Slog.d(TAG, "Removing dead TrustListener.");
442                mTrustListeners.remove(i);
443                i--;
444            } catch (RemoteException e) {
445                Slog.e(TAG, "Exception while notifying TrustListener.", e);
446            }
447        }
448    }
449
450    private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
451        for (int i = 0; i < mTrustListeners.size(); i++) {
452            try {
453                mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
454            } catch (DeadObjectException e) {
455                Slog.d(TAG, "Removing dead TrustListener.");
456                mTrustListeners.remove(i);
457                i--;
458            } catch (RemoteException e) {
459                Slog.e(TAG, "Exception while notifying TrustListener.", e);
460            }
461        }
462    }
463
464    // Plumbing
465
466    private final IBinder mService = new ITrustManager.Stub() {
467        @Override
468        public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
469            enforceReportPermission();
470            mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
471                    .sendToTarget();
472        }
473
474        @Override
475        public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
476            enforceReportPermission();
477            // coalesce refresh messages.
478            mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
479            mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
480        }
481
482        @Override
483        public void reportRequireCredentialEntry(int userId) throws RemoteException {
484            enforceReportPermission();
485            if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) {
486                mHandler.obtainMessage(MSG_REQUIRE_CREDENTIAL_ENTRY, userId, 0).sendToTarget();
487            } else {
488                throw new IllegalArgumentException(
489                        "userId must be an explicit user id or USER_ALL");
490            }
491        }
492
493        @Override
494        public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
495            enforceListenerPermission();
496            mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
497        }
498
499        @Override
500        public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
501            enforceListenerPermission();
502            mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
503        }
504
505        private void enforceReportPermission() {
506            mContext.enforceCallingOrSelfPermission(
507                    Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
508        }
509
510        private void enforceListenerPermission() {
511            mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
512                    "register trust listener");
513        }
514
515        @Override
516        protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
517            mContext.enforceCallingPermission(Manifest.permission.DUMP,
518                    "dumping TrustManagerService");
519            final UserInfo currentUser;
520            final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
521            try {
522                currentUser = ActivityManagerNative.getDefault().getCurrentUser();
523            } catch (RemoteException e) {
524                throw new RuntimeException(e);
525            }
526            mHandler.runWithScissors(new Runnable() {
527                @Override
528                public void run() {
529                    fout.println("Trust manager state:");
530                    for (UserInfo user : userInfos) {
531                        dumpUser(fout, user, user.id == currentUser.id);
532                    }
533                }
534            }, 1500);
535        }
536
537        private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
538            fout.printf(" User \"%s\" (id=%d, flags=%#x)",
539                    user.name, user.id, user.flags);
540            if (isCurrent) {
541                fout.print(" (current)");
542            }
543            fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
544            fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
545            fout.println();
546            fout.println("   Enabled agents:");
547            boolean duplicateSimpleNames = false;
548            ArraySet<String> simpleNames = new ArraySet<String>();
549            for (AgentInfo info : mActiveAgents) {
550                if (info.userId != user.id) { continue; }
551                boolean trusted = info.agent.isTrusted();
552                fout.print("    "); fout.println(info.component.flattenToShortString());
553                fout.print("     bound=" + dumpBool(info.agent.isBound()));
554                fout.print(", connected=" + dumpBool(info.agent.isConnected()));
555                fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
556                fout.print(", trusted=" + dumpBool(trusted));
557                fout.println();
558                if (trusted) {
559                    fout.println("      message=\"" + info.agent.getMessage() + "\"");
560                }
561                if (!info.agent.isConnected()) {
562                    String restartTime = TrustArchive.formatDuration(
563                            info.agent.getScheduledRestartUptimeMillis()
564                                    - SystemClock.uptimeMillis());
565                    fout.println("      restartScheduledAt=" + restartTime);
566                }
567                if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
568                    duplicateSimpleNames = true;
569                }
570            }
571            fout.println("   Events:");
572            mArchive.dump(fout, 50, user.id, "    " /* linePrefix */, duplicateSimpleNames);
573            fout.println();
574        }
575
576        private String dumpBool(boolean b) {
577            return b ? "1" : "0";
578        }
579    };
580
581    private final Handler mHandler = new Handler() {
582        @Override
583        public void handleMessage(Message msg) {
584            switch (msg.what) {
585                case MSG_REGISTER_LISTENER:
586                    addListener((ITrustListener) msg.obj);
587                    break;
588                case MSG_UNREGISTER_LISTENER:
589                    removeListener((ITrustListener) msg.obj);
590                    break;
591                case MSG_DISPATCH_UNLOCK_ATTEMPT:
592                    dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
593                    break;
594                case MSG_ENABLED_AGENTS_CHANGED:
595                    refreshAgentList(UserHandle.USER_ALL);
596                    break;
597                case MSG_REQUIRE_CREDENTIAL_ENTRY:
598                    requireCredentialEntry(msg.arg1);
599                    break;
600            }
601        }
602    };
603
604    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
605        @Override
606        public void onSomePackagesChanged() {
607            refreshAgentList(UserHandle.USER_ALL);
608        }
609
610        @Override
611        public boolean onPackageChanged(String packageName, int uid, String[] components) {
612            // We're interested in all changes, even if just some components get enabled / disabled.
613            return true;
614        }
615
616        @Override
617        public void onPackageDisappeared(String packageName, int reason) {
618            removeAgentsOfPackage(packageName);
619        }
620    };
621
622    private class Receiver extends BroadcastReceiver {
623
624        @Override
625        public void onReceive(Context context, Intent intent) {
626            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
627                    intent.getAction())) {
628                refreshAgentList(getSendingUserId());
629                updateDevicePolicyFeatures();
630            } else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
631                updateUserHasAuthenticated(getSendingUserId());
632            }
633        }
634
635        public void register(Context context) {
636            IntentFilter filter = new IntentFilter();
637            filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
638            filter.addAction(Intent.ACTION_USER_PRESENT);
639            context.registerReceiverAsUser(this,
640                    UserHandle.ALL,
641                    filter,
642                    null /* permission */,
643                    null /* scheduler */);
644        }
645    }
646}
647