OSDN Git Service

Merge "Enforce policy for camera gesture in keyguard" into nyc-mr2-dev
[android-x86/frameworks-base.git] / services / core / java / com / android / server / notification / ManagedServices.java
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.server.notification;
18
19 import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
20 import static android.content.Context.BIND_AUTO_CREATE;
21 import static android.content.Context.BIND_FOREGROUND_SERVICE;
22 import static android.content.Context.DEVICE_POLICY_SERVICE;
23
24 import android.annotation.NonNull;
25 import android.app.ActivityManager;
26 import android.app.PendingIntent;
27 import android.app.admin.DevicePolicyManager;
28 import android.content.BroadcastReceiver;
29 import android.content.ComponentName;
30 import android.content.ContentResolver;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.IntentFilter;
34 import android.content.ServiceConnection;
35 import android.content.pm.ApplicationInfo;
36 import android.content.pm.IPackageManager;
37 import android.content.pm.PackageManager;
38 import android.content.pm.PackageManager.NameNotFoundException;
39 import android.content.pm.ResolveInfo;
40 import android.content.pm.ServiceInfo;
41 import android.content.pm.UserInfo;
42 import android.database.ContentObserver;
43 import android.net.Uri;
44 import android.os.Binder;
45 import android.os.Build;
46 import android.os.Handler;
47 import android.os.IBinder;
48 import android.os.IInterface;
49 import android.os.RemoteException;
50 import android.os.ServiceManager;
51 import android.os.UserHandle;
52 import android.os.UserManager;
53 import android.provider.Settings;
54 import android.text.TextUtils;
55 import android.util.ArraySet;
56 import android.util.Log;
57 import android.util.Slog;
58 import android.util.SparseArray;
59
60 import com.android.server.notification.NotificationManagerService.DumpFilter;
61
62 import java.io.PrintWriter;
63 import java.util.ArrayList;
64 import java.util.Arrays;
65 import java.util.HashSet;
66 import java.util.List;
67 import java.util.Objects;
68 import java.util.Set;
69
70 /**
71  * Manages the lifecycle of application-provided services bound by system server.
72  *
73  * Services managed by this helper must have:
74  *  - An associated system settings value with a list of enabled component names.
75  *  - A well-known action for services to use in their intent-filter.
76  *  - A system permission for services to require in order to ensure system has exclusive binding.
77  *  - A settings page for user configuration of enabled services, and associated intent action.
78  *  - A remote interface definition (aidl) provided by the service used for communication.
79  */
80 abstract public class ManagedServices {
81     protected final String TAG = getClass().getSimpleName();
82     protected final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
83
84     protected static final String ENABLED_SERVICES_SEPARATOR = ":";
85
86     protected final Context mContext;
87     protected final Object mMutex;
88     private final UserProfiles mUserProfiles;
89     private final SettingsObserver mSettingsObserver;
90     private final IPackageManager mPm;
91     private final Config mConfig;
92     private ArraySet<String> mRestored;
93
94     // contains connections to all connected services, including app services
95     // and system services
96     private final ArrayList<ManagedServiceInfo> mServices = new ArrayList<ManagedServiceInfo>();
97     // things that will be put into mServices as soon as they're ready
98     private final ArrayList<String> mServicesBinding = new ArrayList<String>();
99     // lists the component names of all enabled (and therefore potentially connected)
100     // app services for current profiles.
101     private ArraySet<ComponentName> mEnabledServicesForCurrentProfiles
102             = new ArraySet<ComponentName>();
103     // Just the packages from mEnabledServicesForCurrentProfiles
104     private ArraySet<String> mEnabledServicesPackageNames = new ArraySet<String>();
105     // List of packages in restored setting across all mUserProfiles, for quick
106     // filtering upon package updates.
107     private ArraySet<String> mRestoredPackages = new ArraySet<>();
108     // List of enabled packages that have nevertheless asked not to be run
109     private ArraySet<ComponentName> mSnoozingForCurrentProfiles = new ArraySet<>();
110
111
112     // Kept to de-dupe user change events (experienced after boot, when we receive a settings and a
113     // user change).
114     private int[] mLastSeenProfileIds;
115
116     private final BroadcastReceiver mRestoreReceiver;
117
118     public ManagedServices(Context context, Handler handler, Object mutex,
119             UserProfiles userProfiles) {
120         mContext = context;
121         mMutex = mutex;
122         mUserProfiles = userProfiles;
123         mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
124         mConfig = getConfig();
125         mSettingsObserver = new SettingsObserver(handler);
126
127         mRestoreReceiver = new SettingRestoredReceiver();
128         IntentFilter filter = new IntentFilter(Intent.ACTION_SETTING_RESTORED);
129         context.registerReceiver(mRestoreReceiver, filter);
130         rebuildRestoredPackages();
131     }
132
133     class SettingRestoredReceiver extends BroadcastReceiver {
134         @Override
135         public void onReceive(Context context, Intent intent) {
136             if (Intent.ACTION_SETTING_RESTORED.equals(intent.getAction())) {
137                 String element = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
138                 if (Objects.equals(element, mConfig.secureSettingName)
139                         || Objects.equals(element, mConfig.secondarySettingName)) {
140                     String prevValue = intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
141                     String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
142                     settingRestored(element, prevValue, newValue, getSendingUserId());
143                 }
144             }
145         }
146     }
147
148     abstract protected Config getConfig();
149
150     private String getCaption() {
151         return mConfig.caption;
152     }
153
154     abstract protected IInterface asInterface(IBinder binder);
155
156     abstract protected boolean checkType(IInterface service);
157
158     abstract protected void onServiceAdded(ManagedServiceInfo info);
159
160     protected List<ManagedServiceInfo> getServices() {
161         synchronized (mMutex) {
162             List<ManagedServiceInfo> services = new ArrayList<>(mServices);
163             return services;
164         }
165     }
166
167     protected void onServiceRemovedLocked(ManagedServiceInfo removed) { }
168
169     private ManagedServiceInfo newServiceInfo(IInterface service,
170             ComponentName component, int userid, boolean isSystem, ServiceConnection connection,
171             int targetSdkVersion) {
172         return new ManagedServiceInfo(service, component, userid, isSystem, connection,
173                 targetSdkVersion);
174     }
175
176     public void onBootPhaseAppsCanStart() {
177         mSettingsObserver.observe();
178     }
179
180     public void dump(PrintWriter pw, DumpFilter filter) {
181         pw.println("    All " + getCaption() + "s (" + mEnabledServicesForCurrentProfiles.size()
182                 + ") enabled for current profiles:");
183         for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
184             if (filter != null && !filter.matches(cmpt)) continue;
185             pw.println("      " + cmpt);
186         }
187
188         pw.println("    Live " + getCaption() + "s (" + mServices.size() + "):");
189         for (ManagedServiceInfo info : mServices) {
190             if (filter != null && !filter.matches(info.component)) continue;
191             pw.println("      " + info.component
192                     + " (user " + info.userid + "): " + info.service
193                     + (info.isSystem?" SYSTEM":"")
194                     + (info.isGuest(this)?" GUEST":""));
195         }
196
197         pw.println("    Snoozed " + getCaption() + "s (" +
198                 mSnoozingForCurrentProfiles.size() + "):");
199         for (ComponentName name : mSnoozingForCurrentProfiles) {
200             pw.println("      " + name.flattenToShortString());
201         }
202     }
203
204     // By convention, restored settings are replicated to another settings
205     // entry, named similarly but with a disambiguation suffix.
206     public static String restoredSettingName(String setting) {
207         return setting + ":restored";
208     }
209
210     // The OS has done a restore of this service's saved state.  We clone it to the
211     // 'restored' reserve, and then once we return and the actual write to settings is
212     // performed, our observer will do the work of maintaining the restored vs live
213     // settings data.
214     public void settingRestored(String element, String oldValue, String newValue, int userid) {
215         if (DEBUG) Slog.d(TAG, "Restored managed service setting: " + element
216                 + " ovalue=" + oldValue + " nvalue=" + newValue);
217         if (mConfig.secureSettingName.equals(element) ||
218                 mConfig.secondarySettingName.equals(element)) {
219             if (element != null) {
220                 Settings.Secure.putStringForUser(mContext.getContentResolver(),
221                         restoredSettingName(element),
222                         newValue,
223                         userid);
224                 if (mConfig.secureSettingName.equals(element)) {
225                     updateSettingsAccordingToInstalledServices(element, userid);
226                 }
227                 rebuildRestoredPackages();
228             }
229         }
230     }
231
232     public boolean isComponentEnabledForPackage(String pkg) {
233         return mEnabledServicesPackageNames.contains(pkg);
234     }
235
236     public void onPackagesChanged(boolean removingPackage, String[] pkgList) {
237         if (DEBUG) Slog.d(TAG, "onPackagesChanged removingPackage=" + removingPackage
238                 + " pkgList=" + (pkgList == null ? null : Arrays.asList(pkgList))
239                 + " mEnabledServicesPackageNames=" + mEnabledServicesPackageNames);
240         boolean anyServicesInvolved = false;
241
242         if (pkgList != null && (pkgList.length > 0)) {
243             for (String pkgName : pkgList) {
244                 if (mEnabledServicesPackageNames.contains(pkgName) ||
245                         mRestoredPackages.contains(pkgName)) {
246                     anyServicesInvolved = true;
247                 }
248             }
249         }
250
251         if (anyServicesInvolved) {
252             // if we're not replacing a package, clean up orphaned bits
253             if (removingPackage) {
254                 updateSettingsAccordingToInstalledServices();
255                 rebuildRestoredPackages();
256             }
257             // make sure we're still bound to any of our services who may have just upgraded
258             rebindServices(false);
259         }
260     }
261
262     public void onUserSwitched(int user) {
263         if (DEBUG) Slog.d(TAG, "onUserSwitched u=" + user);
264         rebuildRestoredPackages();
265         if (Arrays.equals(mLastSeenProfileIds, mUserProfiles.getCurrentProfileIds())) {
266             if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices().");
267             return;
268         }
269         rebindServices(true);
270     }
271
272     public void onUserUnlocked(int user) {
273         if (DEBUG) Slog.d(TAG, "onUserUnlocked u=" + user);
274         rebuildRestoredPackages();
275         rebindServices(false);
276     }
277
278     public ManagedServiceInfo getServiceFromTokenLocked(IInterface service) {
279         if (service == null) {
280             return null;
281         }
282         final IBinder token = service.asBinder();
283         final int N = mServices.size();
284         for (int i = 0; i < N; i++) {
285             final ManagedServiceInfo info = mServices.get(i);
286             if (info.service.asBinder() == token) return info;
287         }
288         return null;
289     }
290
291     public ManagedServiceInfo checkServiceTokenLocked(IInterface service) {
292         checkNotNull(service);
293         ManagedServiceInfo info = getServiceFromTokenLocked(service);
294         if (info != null) {
295             return info;
296         }
297         throw new SecurityException("Disallowed call from unknown " + getCaption() + ": "
298                 + service);
299     }
300
301     public void unregisterService(IInterface service, int userid) {
302         checkNotNull(service);
303         // no need to check permissions; if your service binder is in the list,
304         // that's proof that you had permission to add it in the first place
305         unregisterServiceImpl(service, userid);
306     }
307
308     public void registerService(IInterface service, ComponentName component, int userid) {
309         checkNotNull(service);
310         ManagedServiceInfo info = registerServiceImpl(service, component, userid);
311         if (info != null) {
312             onServiceAdded(info);
313         }
314     }
315
316     /**
317      * Add a service to our callbacks. The lifecycle of this service is managed externally,
318      * but unlike a system service, it should not be considered privledged.
319      * */
320     public void registerGuestService(ManagedServiceInfo guest) {
321         checkNotNull(guest.service);
322         if (!checkType(guest.service)) {
323             throw new IllegalArgumentException();
324         }
325         if (registerServiceImpl(guest) != null) {
326             onServiceAdded(guest);
327         }
328     }
329
330     public void setComponentState(ComponentName component, boolean enabled) {
331         boolean previous = !mSnoozingForCurrentProfiles.contains(component);
332         if (previous == enabled) {
333             return;
334         }
335
336         if (enabled) {
337             mSnoozingForCurrentProfiles.remove(component);
338         } else {
339             mSnoozingForCurrentProfiles.add(component);
340         }
341
342         // State changed
343         if (DEBUG) {
344             Slog.d(TAG, ((enabled) ? "Enabling " : "Disabling ") + "component " +
345                     component.flattenToShortString());
346         }
347
348
349         synchronized (mMutex) {
350             final int[] userIds = mUserProfiles.getCurrentProfileIds();
351
352             for (int userId : userIds) {
353                 if (enabled) {
354                     registerServiceLocked(component, userId);
355                 } else {
356                     unregisterServiceLocked(component, userId);
357                 }
358             }
359         }
360     }
361
362     private void rebuildRestoredPackages() {
363         mRestoredPackages.clear();
364         String secureSettingName = restoredSettingName(mConfig.secureSettingName);
365         String secondarySettingName = mConfig.secondarySettingName == null
366                 ? null : restoredSettingName(mConfig.secondarySettingName);
367         int[] userIds = mUserProfiles.getCurrentProfileIds();
368         final int N = userIds.length;
369         for (int i = 0; i < N; ++i) {
370             ArraySet<ComponentName> names =
371                     loadComponentNamesFromSetting(secureSettingName, userIds[i]);
372             if (secondarySettingName != null) {
373                 names.addAll(loadComponentNamesFromSetting(secondarySettingName, userIds[i]));
374             }
375             for (ComponentName name : names) {
376                 mRestoredPackages.add(name.getPackageName());
377             }
378         }
379     }
380
381
382     protected @NonNull ArraySet<ComponentName> loadComponentNamesFromSetting(String settingName,
383             int userId) {
384         final ContentResolver cr = mContext.getContentResolver();
385         String settingValue = Settings.Secure.getStringForUser(
386             cr,
387             settingName,
388             userId);
389         if (TextUtils.isEmpty(settingValue))
390             return new ArraySet<>();
391         String[] restored = settingValue.split(ENABLED_SERVICES_SEPARATOR);
392         ArraySet<ComponentName> result = new ArraySet<>(restored.length);
393         for (int i = 0; i < restored.length; i++) {
394             ComponentName value = ComponentName.unflattenFromString(restored[i]);
395             if (null != value) {
396                 result.add(value);
397             }
398         }
399         return result;
400     }
401
402     private void storeComponentsToSetting(Set<ComponentName> components,
403                                           String settingName,
404                                           int userId) {
405         String[] componentNames = null;
406         if (null != components) {
407             componentNames = new String[components.size()];
408             int index = 0;
409             for (ComponentName c: components) {
410                 componentNames[index++] = c.flattenToString();
411             }
412         }
413         final String value = (componentNames == null) ? "" :
414                 TextUtils.join(ENABLED_SERVICES_SEPARATOR, componentNames);
415         final ContentResolver cr = mContext.getContentResolver();
416         Settings.Secure.putStringForUser(
417             cr,
418             settingName,
419             value,
420             userId);
421     }
422
423     /**
424      * Remove access for any services that no longer exist.
425      */
426     private void updateSettingsAccordingToInstalledServices() {
427         int[] userIds = mUserProfiles.getCurrentProfileIds();
428         final int N = userIds.length;
429         for (int i = 0; i < N; ++i) {
430             updateSettingsAccordingToInstalledServices(mConfig.secureSettingName, userIds[i]);
431             if (mConfig.secondarySettingName != null) {
432                 updateSettingsAccordingToInstalledServices(
433                         mConfig.secondarySettingName, userIds[i]);
434             }
435         }
436         rebuildRestoredPackages();
437     }
438
439     protected Set<ComponentName> queryPackageForServices(String packageName, int userId) {
440         Set<ComponentName> installed = new ArraySet<>();
441         final PackageManager pm = mContext.getPackageManager();
442         Intent queryIntent = new Intent(mConfig.serviceInterface);
443         if (!TextUtils.isEmpty(packageName)) {
444             queryIntent.setPackage(packageName);
445         }
446         List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser(
447                 queryIntent,
448                 PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
449                 userId);
450         if (DEBUG)
451             Slog.v(TAG, mConfig.serviceInterface + " services: " + installedServices);
452         if (installedServices != null) {
453             for (int i = 0, count = installedServices.size(); i < count; i++) {
454                 ResolveInfo resolveInfo = installedServices.get(i);
455                 ServiceInfo info = resolveInfo.serviceInfo;
456
457                 ComponentName component = new ComponentName(info.packageName, info.name);
458                 if (!mConfig.bindPermission.equals(info.permission)) {
459                     Slog.w(TAG, "Skipping " + getCaption() + " service "
460                         + info.packageName + "/" + info.name
461                         + ": it does not require the permission "
462                         + mConfig.bindPermission);
463                     continue;
464                 }
465                 installed.add(component);
466             }
467         }
468         return installed;
469     }
470
471     private void updateSettingsAccordingToInstalledServices(String setting, int userId) {
472         boolean restoredChanged = false;
473         boolean currentChanged = false;
474         Set<ComponentName> restored =
475                 loadComponentNamesFromSetting(restoredSettingName(setting), userId);
476         Set<ComponentName> current =
477                 loadComponentNamesFromSetting(setting, userId);
478         // Load all services for all packages.
479         Set<ComponentName> installed = queryPackageForServices(null, userId);
480
481         ArraySet<ComponentName> retained = new ArraySet<>();
482
483         for (ComponentName component : installed) {
484             if (null != restored) {
485                 boolean wasRestored = restored.remove(component);
486                 if (wasRestored) {
487                     // Freshly installed package has service that was mentioned in restored setting.
488                     if (DEBUG)
489                         Slog.v(TAG, "Restoring " + component + " for user " + userId);
490                     restoredChanged = true;
491                     currentChanged = true;
492                     retained.add(component);
493                     continue;
494                 }
495             }
496
497             if (null != current) {
498                 if (current.contains(component))
499                     retained.add(component);
500             }
501         }
502
503         currentChanged |= ((current == null ? 0 : current.size()) != retained.size());
504
505         if (currentChanged) {
506             if (DEBUG) Slog.v(TAG, "List of  " + getCaption() + " services was updated " + current);
507             storeComponentsToSetting(retained, setting, userId);
508         }
509
510         if (restoredChanged) {
511             if (DEBUG) Slog.v(TAG,
512                     "List of  " + getCaption() + " restored services was updated " + restored);
513             storeComponentsToSetting(restored, restoredSettingName(setting), userId);
514         }
515     }
516
517     /**
518      * Called whenever packages change, the user switches, or the secure setting
519      * is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
520      */
521     private void rebindServices(boolean forceRebind) {
522         if (DEBUG) Slog.d(TAG, "rebindServices");
523         final int[] userIds = mUserProfiles.getCurrentProfileIds();
524         final int nUserIds = userIds.length;
525
526         final SparseArray<ArraySet<ComponentName>> componentsByUser = new SparseArray<>();
527
528         for (int i = 0; i < nUserIds; ++i) {
529             componentsByUser.put(userIds[i],
530                     loadComponentNamesFromSetting(mConfig.secureSettingName, userIds[i]));
531             if (mConfig.secondarySettingName != null) {
532                 componentsByUser.get(userIds[i]).addAll(
533                         loadComponentNamesFromSetting(mConfig.secondarySettingName, userIds[i]));
534             }
535         }
536
537         final ArrayList<ManagedServiceInfo> removableBoundServices = new ArrayList<>();
538         final SparseArray<Set<ComponentName>> toAdd = new SparseArray<>();
539
540         synchronized (mMutex) {
541             // Rebind to non-system services if user switched
542             for (ManagedServiceInfo service : mServices) {
543                 if (!service.isSystem && !service.isGuest(this)) {
544                     removableBoundServices.add(service);
545                 }
546             }
547
548             mEnabledServicesForCurrentProfiles.clear();
549             mEnabledServicesPackageNames.clear();
550
551             for (int i = 0; i < nUserIds; ++i) {
552                 // decode the list of components
553                 final ArraySet<ComponentName> userComponents = componentsByUser.get(userIds[i]);
554                 if (null == userComponents) {
555                     toAdd.put(userIds[i], new ArraySet<ComponentName>());
556                     continue;
557                 }
558
559                 final Set<ComponentName> add = new HashSet<>(userComponents);
560                 add.removeAll(mSnoozingForCurrentProfiles);
561
562                 toAdd.put(userIds[i], add);
563
564                 mEnabledServicesForCurrentProfiles.addAll(userComponents);
565
566                 for (int j = 0; j < userComponents.size(); j++) {
567                     final ComponentName component = userComponents.valueAt(j);
568                     mEnabledServicesPackageNames.add(component.getPackageName());
569                 }
570             }
571         }
572
573         for (ManagedServiceInfo info : removableBoundServices) {
574             final ComponentName component = info.component;
575             final int oldUser = info.userid;
576             final Set<ComponentName> allowedComponents = toAdd.get(info.userid);
577             if (allowedComponents != null) {
578                 if (allowedComponents.contains(component) && !forceRebind) {
579                     // Already bound, don't need to bind again.
580                     allowedComponents.remove(component);
581                 } else {
582                     // No longer allowed to be bound, or must rebind.
583                     Slog.v(TAG, "disabling " + getCaption() + " for user "
584                             + oldUser + ": " + component);
585                     unregisterService(component, oldUser);
586                 }
587             }
588         }
589
590         for (int i = 0; i < nUserIds; ++i) {
591             final Set<ComponentName> add = toAdd.get(userIds[i]);
592             for (ComponentName component : add) {
593                 try {
594                     ServiceInfo info = mPm.getServiceInfo(component,
595                             PackageManager.MATCH_DIRECT_BOOT_AWARE
596                                     | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userIds[i]);
597                     if (info == null || !mConfig.bindPermission.equals(info.permission)) {
598                         Slog.w(TAG, "Skipping " + getCaption() + " service " + component
599                                 + ": it does not require the permission " + mConfig.bindPermission);
600                         continue;
601                     }
602                     Slog.v(TAG,
603                             "enabling " + getCaption() + " for " + userIds[i] + ": " + component);
604                     registerService(component, userIds[i]);
605                 } catch (RemoteException e) {
606                     e.rethrowFromSystemServer();
607                 }
608             }
609         }
610
611         mLastSeenProfileIds = userIds;
612     }
613
614     /**
615      * Version of registerService that takes the name of a service component to bind to.
616      */
617     private void registerService(final ComponentName name, final int userid) {
618         synchronized (mMutex) {
619             registerServiceLocked(name, userid);
620         }
621     }
622
623     /**
624      * Inject a system service into the management list.
625      */
626     public void registerSystemService(final ComponentName name, final int userid) {
627         synchronized (mMutex) {
628             registerServiceLocked(name, userid, true /* isSystem */);
629         }
630     }
631
632     private void registerServiceLocked(final ComponentName name, final int userid) {
633         registerServiceLocked(name, userid, false /* isSystem */);
634     }
635
636     private void registerServiceLocked(final ComponentName name, final int userid,
637             final boolean isSystem) {
638         if (DEBUG) Slog.v(TAG, "registerService: " + name + " u=" + userid);
639
640         final String servicesBindingTag = name.toString() + "/" + userid;
641         if (mServicesBinding.contains(servicesBindingTag)) {
642             // stop registering this thing already! we're working on it
643             return;
644         }
645         mServicesBinding.add(servicesBindingTag);
646
647         final int N = mServices.size();
648         for (int i = N - 1; i >= 0; i--) {
649             final ManagedServiceInfo info = mServices.get(i);
650             if (name.equals(info.component)
651                 && info.userid == userid) {
652                 // cut old connections
653                 if (DEBUG) Slog.v(TAG, "    disconnecting old " + getCaption() + ": "
654                     + info.service);
655                 removeServiceLocked(i);
656                 if (info.connection != null) {
657                     mContext.unbindService(info.connection);
658                 }
659             }
660         }
661
662         Intent intent = new Intent(mConfig.serviceInterface);
663         intent.setComponent(name);
664
665         intent.putExtra(Intent.EXTRA_CLIENT_LABEL, mConfig.clientLabel);
666
667         final PendingIntent pendingIntent = PendingIntent.getActivity(
668             mContext, 0, new Intent(mConfig.settingsAction), 0);
669         intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent);
670
671         ApplicationInfo appInfo = null;
672         try {
673             appInfo = mContext.getPackageManager().getApplicationInfo(
674                 name.getPackageName(), 0);
675         } catch (NameNotFoundException e) {
676             // Ignore if the package doesn't exist we won't be able to bind to the service.
677         }
678         final int targetSdkVersion =
679             appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE;
680
681         try {
682             if (DEBUG) Slog.v(TAG, "binding: " + intent);
683             ServiceConnection serviceConnection = new ServiceConnection() {
684                 IInterface mService;
685
686                 @Override
687                 public void onServiceConnected(ComponentName name, IBinder binder) {
688                     boolean added = false;
689                     ManagedServiceInfo info = null;
690                     synchronized (mMutex) {
691                         mServicesBinding.remove(servicesBindingTag);
692                         try {
693                             mService = asInterface(binder);
694                             info = newServiceInfo(mService, name,
695                                 userid, isSystem, this, targetSdkVersion);
696                             binder.linkToDeath(info, 0);
697                             added = mServices.add(info);
698                         } catch (RemoteException e) {
699                             // already dead
700                         }
701                     }
702                     if (added) {
703                         onServiceAdded(info);
704                     }
705                 }
706
707                 @Override
708                 public void onServiceDisconnected(ComponentName name) {
709                     Slog.v(TAG, getCaption() + " connection lost: " + name);
710                 }
711             };
712             if (!mContext.bindServiceAsUser(intent,
713                 serviceConnection,
714                 BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT,
715                 new UserHandle(userid))) {
716                 mServicesBinding.remove(servicesBindingTag);
717                 Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent);
718                 return;
719             }
720         } catch (SecurityException ex) {
721             Slog.e(TAG, "Unable to bind " + getCaption() + " service: " + intent, ex);
722             return;
723         }
724     }
725
726     /**
727      * Remove a service for the given user by ComponentName
728      */
729     private void unregisterService(ComponentName name, int userid) {
730         synchronized (mMutex) {
731             unregisterServiceLocked(name, userid);
732         }
733     }
734
735     private void unregisterServiceLocked(ComponentName name, int userid) {
736         final int N = mServices.size();
737         for (int i = N - 1; i >= 0; i--) {
738             final ManagedServiceInfo info = mServices.get(i);
739             if (name.equals(info.component)
740                 && info.userid == userid) {
741                 removeServiceLocked(i);
742                 if (info.connection != null) {
743                     try {
744                         mContext.unbindService(info.connection);
745                     } catch (IllegalArgumentException ex) {
746                         // something happened to the service: we think we have a connection
747                         // but it's bogus.
748                         Slog.e(TAG, getCaption() + " " + name + " could not be unbound: " + ex);
749                     }
750                 }
751             }
752         }
753     }
754
755     /**
756      * Removes a service from the list but does not unbind
757      *
758      * @return the removed service.
759      */
760     private ManagedServiceInfo removeServiceImpl(IInterface service, final int userid) {
761         if (DEBUG) Slog.d(TAG, "removeServiceImpl service=" + service + " u=" + userid);
762         ManagedServiceInfo serviceInfo = null;
763         synchronized (mMutex) {
764             final int N = mServices.size();
765             for (int i = N - 1; i >= 0; i--) {
766                 final ManagedServiceInfo info = mServices.get(i);
767                 if (info.service.asBinder() == service.asBinder()
768                         && info.userid == userid) {
769                     if (DEBUG) Slog.d(TAG, "Removing active service " + info.component);
770                     serviceInfo = removeServiceLocked(i);
771                 }
772             }
773         }
774         return serviceInfo;
775     }
776
777     private ManagedServiceInfo removeServiceLocked(int i) {
778         final ManagedServiceInfo info = mServices.remove(i);
779         onServiceRemovedLocked(info);
780         return info;
781     }
782
783     private void checkNotNull(IInterface service) {
784         if (service == null) {
785             throw new IllegalArgumentException(getCaption() + " must not be null");
786         }
787     }
788
789     private ManagedServiceInfo registerServiceImpl(final IInterface service,
790             final ComponentName component, final int userid) {
791         ManagedServiceInfo info = newServiceInfo(service, component, userid,
792                 true /*isSystem*/, null /*connection*/, Build.VERSION_CODES.LOLLIPOP);
793         return registerServiceImpl(info);
794     }
795
796     private ManagedServiceInfo registerServiceImpl(ManagedServiceInfo info) {
797         synchronized (mMutex) {
798             try {
799                 info.service.asBinder().linkToDeath(info, 0);
800                 mServices.add(info);
801                 return info;
802             } catch (RemoteException e) {
803                 // already dead
804             }
805         }
806         return null;
807     }
808
809     /**
810      * Removes a service from the list and unbinds.
811      */
812     private void unregisterServiceImpl(IInterface service, int userid) {
813         ManagedServiceInfo info = removeServiceImpl(service, userid);
814         if (info != null && info.connection != null && !info.isGuest(this)) {
815             mContext.unbindService(info.connection);
816         }
817     }
818
819     private class SettingsObserver extends ContentObserver {
820         private final Uri mSecureSettingsUri = Settings.Secure.getUriFor(mConfig.secureSettingName);
821         private final Uri mSecondarySettingsUri;
822
823         private SettingsObserver(Handler handler) {
824             super(handler);
825             if (mConfig.secondarySettingName != null) {
826                 mSecondarySettingsUri = Settings.Secure.getUriFor(mConfig.secondarySettingName);
827             } else {
828                 mSecondarySettingsUri = null;
829             }
830         }
831
832         private void observe() {
833             ContentResolver resolver = mContext.getContentResolver();
834             resolver.registerContentObserver(mSecureSettingsUri,
835                     false, this, UserHandle.USER_ALL);
836             if (mSecondarySettingsUri != null) {
837                 resolver.registerContentObserver(mSecondarySettingsUri,
838                         false, this, UserHandle.USER_ALL);
839             }
840             update(null);
841         }
842
843         @Override
844         public void onChange(boolean selfChange, Uri uri) {
845             update(uri);
846         }
847
848         private void update(Uri uri) {
849             if (uri == null || mSecureSettingsUri.equals(uri)
850                     || uri.equals(mSecondarySettingsUri)) {
851                 if (DEBUG) Slog.d(TAG, "Setting changed: uri=" + uri);
852                 rebindServices(false);
853                 rebuildRestoredPackages();
854             }
855         }
856     }
857
858     public class ManagedServiceInfo implements IBinder.DeathRecipient {
859         public IInterface service;
860         public ComponentName component;
861         public int userid;
862         public boolean isSystem;
863         public ServiceConnection connection;
864         public int targetSdkVersion;
865
866         public ManagedServiceInfo(IInterface service, ComponentName component,
867                 int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion) {
868             this.service = service;
869             this.component = component;
870             this.userid = userid;
871             this.isSystem = isSystem;
872             this.connection = connection;
873             this.targetSdkVersion = targetSdkVersion;
874         }
875
876         public boolean isGuest(ManagedServices host) {
877             return ManagedServices.this != host;
878         }
879
880         public ManagedServices getOwner() {
881             return ManagedServices.this;
882         }
883
884         @Override
885         public String toString() {
886             return new StringBuilder("ManagedServiceInfo[")
887                     .append("component=").append(component)
888                     .append(",userid=").append(userid)
889                     .append(",isSystem=").append(isSystem)
890                     .append(",targetSdkVersion=").append(targetSdkVersion)
891                     .append(",connection=").append(connection == null ? null : "<connection>")
892                     .append(",service=").append(service)
893                     .append(']').toString();
894         }
895
896         public boolean enabledAndUserMatches(int nid) {
897             if (!isEnabledForCurrentProfiles()) {
898                 return false;
899             }
900             if (this.userid == UserHandle.USER_ALL) return true;
901             if (this.isSystem) return true;
902             if (nid == UserHandle.USER_ALL || nid == this.userid) return true;
903             return supportsProfiles()
904                     && mUserProfiles.isCurrentProfile(nid)
905                     && isPermittedForProfile(nid);
906         }
907
908         public boolean supportsProfiles() {
909             return targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP;
910         }
911
912         @Override
913         public void binderDied() {
914             if (DEBUG) Slog.d(TAG, "binderDied");
915             // Remove the service, but don't unbind from the service. The system will bring the
916             // service back up, and the onServiceConnected handler will read the service with the
917             // new binding. If this isn't a bound service, and is just a registered
918             // service, just removing it from the list is all we need to do anyway.
919             removeServiceImpl(this.service, this.userid);
920         }
921
922         /** convenience method for looking in mEnabledServicesForCurrentProfiles */
923         public boolean isEnabledForCurrentProfiles() {
924             if (this.isSystem) return true;
925             if (this.connection == null) return false;
926             return mEnabledServicesForCurrentProfiles.contains(this.component);
927         }
928
929         /**
930          * Returns true if this service is allowed to receive events for the given userId. A
931          * managed profile owner can disallow non-system services running outside of the profile
932          * from receiving events from the profile.
933          */
934         public boolean isPermittedForProfile(int userId) {
935             if (!mUserProfiles.isManagedProfile(userId)) {
936                 return true;
937             }
938             DevicePolicyManager dpm =
939                     (DevicePolicyManager) mContext.getSystemService(DEVICE_POLICY_SERVICE);
940             final long identity = Binder.clearCallingIdentity();
941             try {
942                 return dpm.isNotificationListenerServicePermitted(
943                         component.getPackageName(), userId);
944             } finally {
945                 Binder.restoreCallingIdentity(identity);
946             }
947         }
948     }
949
950     /** convenience method for looking in mEnabledServicesForCurrentProfiles */
951     public boolean isComponentEnabledForCurrentProfiles(ComponentName component) {
952         return mEnabledServicesForCurrentProfiles.contains(component);
953     }
954
955     public static class UserProfiles {
956         // Profiles of the current user.
957         private final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
958
959         public void updateCache(@NonNull Context context) {
960             UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
961             if (userManager != null) {
962                 int currentUserId = ActivityManager.getCurrentUser();
963                 List<UserInfo> profiles = userManager.getProfiles(currentUserId);
964                 synchronized (mCurrentProfiles) {
965                     mCurrentProfiles.clear();
966                     for (UserInfo user : profiles) {
967                         mCurrentProfiles.put(user.id, user);
968                     }
969                 }
970             }
971         }
972
973         public int[] getCurrentProfileIds() {
974             synchronized (mCurrentProfiles) {
975                 int[] users = new int[mCurrentProfiles.size()];
976                 final int N = mCurrentProfiles.size();
977                 for (int i = 0; i < N; ++i) {
978                     users[i] = mCurrentProfiles.keyAt(i);
979                 }
980                 return users;
981             }
982         }
983
984         public boolean isCurrentProfile(int userId) {
985             synchronized (mCurrentProfiles) {
986                 return mCurrentProfiles.get(userId) != null;
987             }
988         }
989
990         public boolean isManagedProfile(int userId) {
991             synchronized (mCurrentProfiles) {
992                 UserInfo user = mCurrentProfiles.get(userId);
993                 return user != null && user.isManagedProfile();
994             }
995         }
996     }
997
998     public static class Config {
999         public String caption;
1000         public String serviceInterface;
1001         public String secureSettingName;
1002         public String secondarySettingName;
1003         public String bindPermission;
1004         public String settingsAction;
1005         public int clientLabel;
1006     }
1007 }