OSDN Git Service

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