Loading services/core/java/com/android/server/ServiceWatcher.java +80 −52 Original line number Diff line number Diff line Loading @@ -185,9 +185,49 @@ public class ServiceWatcher implements ServiceConnection { private final Handler mHandler; private final Intent mIntent; private final PackageMonitor mPackageMonitor = new PackageMonitor() { @Override public boolean onPackageChanged(String packageName, int uid, String[] components) { return true; } @Override public void onSomePackagesChanged() { onBestServiceChanged(false); } }; private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action == null) { return; } int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); if (userId == UserHandle.USER_NULL) { return; } switch (action) { case Intent.ACTION_USER_SWITCHED: onUserSwitched(userId); break; case Intent.ACTION_USER_UNLOCKED: onUserUnlocked(userId); break; default: break; } } }; @Nullable private final OnBindRunner mOnBind; @Nullable private final Runnable mOnUnbind; // write from caller thread only, read anywhere private volatile boolean mRegistered; // read/write from handler thread only private int mCurrentUserId; Loading Loading @@ -225,79 +265,67 @@ public class ServiceWatcher implements ServiceConnection { } /** * Register this class, which will start the process of determining the best matching service * and maintaining a binding to it. Will return false and fail if there are no possible matching * services at the time this functions is called. * Returns true if there is at least one component that could satisfy the ServiceWatcher's * constraints. */ public boolean register() { if (mContext.getPackageManager().queryIntentServicesAsUser(mIntent, public boolean checkServiceResolves() { return !mContext.getPackageManager().queryIntentServicesAsUser(mIntent, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE | MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).isEmpty()) { return false; UserHandle.USER_SYSTEM).isEmpty(); } new PackageMonitor() { @Override public boolean onPackageChanged(String packageName, int uid, String[] components) { return true; } /** * Starts the process of determining the best matching service and maintaining a binding to it. */ public void register() { Preconditions.checkState(!mRegistered); @Override public void onSomePackagesChanged() { onBestServiceChanged(false); } }.register(mContext, UserHandle.ALL, true, mHandler); mPackageMonitor.register(mContext, UserHandle.ALL, true, mHandler); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_SWITCHED); intentFilter.addAction(Intent.ACTION_USER_UNLOCKED); mContext.registerReceiverAsUser(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action == null) { return; } int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); if (userId == UserHandle.USER_NULL) { return; } mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, intentFilter, null, mHandler); switch (action) { case Intent.ACTION_USER_SWITCHED: onUserSwitched(userId); break; case Intent.ACTION_USER_UNLOCKED: onUserUnlocked(userId); break; default: break; } mCurrentUserId = ActivityManager.getCurrentUser(); mRegistered = true; mHandler.post(() -> onBestServiceChanged(false)); } }, UserHandle.ALL, intentFilter, null, mHandler); mCurrentUserId = ActivityManager.getCurrentUser(); /** * Stops the process of determining the best matching service and releases any binding. */ public void unregister() { Preconditions.checkState(mRegistered); mRegistered = false; mPackageMonitor.unregister(); mContext.unregisterReceiver(mBroadcastReceiver); mHandler.post(() -> onBestServiceChanged(false)); return true; } private void onBestServiceChanged(boolean forceRebind) { Preconditions.checkState(Looper.myLooper() == mHandler.getLooper()); ServiceInfo bestServiceInfo = ServiceInfo.NONE; if (mRegistered) { List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServicesAsUser( mIntent, GET_META_DATA | MATCH_DIRECT_BOOT_AUTO | MATCH_SYSTEM_ONLY, mCurrentUserId); ServiceInfo bestServiceInfo = ServiceInfo.NONE; for (ResolveInfo resolveInfo : resolveInfos) { ServiceInfo serviceInfo = new ServiceInfo(resolveInfo, mCurrentUserId); if (serviceInfo.compareTo(bestServiceInfo) > 0) { bestServiceInfo = serviceInfo; } } } if (forceRebind || !bestServiceInfo.equals(mTargetService)) { rebind(bestServiceInfo); Loading services/core/java/com/android/server/location/GeocoderProxy.java +5 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,11 @@ public class GeocoderProxy { } private boolean register() { return mServiceWatcher.register(); boolean resolves = mServiceWatcher.checkServiceResolves(); if (resolves) { mServiceWatcher.register(); } return resolves; } /** Loading services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java +5 −1 Original line number Diff line number Diff line Loading @@ -75,7 +75,11 @@ public class HardwareActivityRecognitionProxy { } private boolean register() { return mServiceWatcher.register(); boolean resolves = mServiceWatcher.checkServiceResolves(); if (resolves) { mServiceWatcher.register(); } return resolves; } private void onBind(IBinder binder, ComponentName service) throws RemoteException { Loading services/core/java/com/android/server/location/ProxyLocationProvider.java +5 −1 Original line number Diff line number Diff line Loading @@ -92,7 +92,11 @@ public class ProxyLocationProvider extends AbstractLocationProvider { } private boolean register() { return mServiceWatcher.register(); boolean resolves = mServiceWatcher.checkServiceResolves(); if (resolves) { mServiceWatcher.register(); } return resolves; } private void onBind(IBinder binder, ComponentName service) throws RemoteException { Loading services/core/java/com/android/server/location/geofence/GeofenceProxy.java +4 −4 Original line number Diff line number Diff line Loading @@ -75,16 +75,16 @@ public final class GeofenceProxy { } private boolean register(Context context) { if (mServiceWatcher.register()) { boolean resolves = mServiceWatcher.checkServiceResolves(); if (resolves) { mServiceWatcher.register(); context.bindServiceAsUser( new Intent(context, GeofenceHardwareService.class), new GeofenceProxyServiceConnection(), Context.BIND_AUTO_CREATE, UserHandle.SYSTEM); return true; } return false; return resolves; } private class GeofenceProxyServiceConnection implements ServiceConnection { Loading Loading
services/core/java/com/android/server/ServiceWatcher.java +80 −52 Original line number Diff line number Diff line Loading @@ -185,9 +185,49 @@ public class ServiceWatcher implements ServiceConnection { private final Handler mHandler; private final Intent mIntent; private final PackageMonitor mPackageMonitor = new PackageMonitor() { @Override public boolean onPackageChanged(String packageName, int uid, String[] components) { return true; } @Override public void onSomePackagesChanged() { onBestServiceChanged(false); } }; private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action == null) { return; } int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); if (userId == UserHandle.USER_NULL) { return; } switch (action) { case Intent.ACTION_USER_SWITCHED: onUserSwitched(userId); break; case Intent.ACTION_USER_UNLOCKED: onUserUnlocked(userId); break; default: break; } } }; @Nullable private final OnBindRunner mOnBind; @Nullable private final Runnable mOnUnbind; // write from caller thread only, read anywhere private volatile boolean mRegistered; // read/write from handler thread only private int mCurrentUserId; Loading Loading @@ -225,79 +265,67 @@ public class ServiceWatcher implements ServiceConnection { } /** * Register this class, which will start the process of determining the best matching service * and maintaining a binding to it. Will return false and fail if there are no possible matching * services at the time this functions is called. * Returns true if there is at least one component that could satisfy the ServiceWatcher's * constraints. */ public boolean register() { if (mContext.getPackageManager().queryIntentServicesAsUser(mIntent, public boolean checkServiceResolves() { return !mContext.getPackageManager().queryIntentServicesAsUser(mIntent, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE | MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).isEmpty()) { return false; UserHandle.USER_SYSTEM).isEmpty(); } new PackageMonitor() { @Override public boolean onPackageChanged(String packageName, int uid, String[] components) { return true; } /** * Starts the process of determining the best matching service and maintaining a binding to it. */ public void register() { Preconditions.checkState(!mRegistered); @Override public void onSomePackagesChanged() { onBestServiceChanged(false); } }.register(mContext, UserHandle.ALL, true, mHandler); mPackageMonitor.register(mContext, UserHandle.ALL, true, mHandler); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_SWITCHED); intentFilter.addAction(Intent.ACTION_USER_UNLOCKED); mContext.registerReceiverAsUser(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action == null) { return; } int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); if (userId == UserHandle.USER_NULL) { return; } mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, intentFilter, null, mHandler); switch (action) { case Intent.ACTION_USER_SWITCHED: onUserSwitched(userId); break; case Intent.ACTION_USER_UNLOCKED: onUserUnlocked(userId); break; default: break; } mCurrentUserId = ActivityManager.getCurrentUser(); mRegistered = true; mHandler.post(() -> onBestServiceChanged(false)); } }, UserHandle.ALL, intentFilter, null, mHandler); mCurrentUserId = ActivityManager.getCurrentUser(); /** * Stops the process of determining the best matching service and releases any binding. */ public void unregister() { Preconditions.checkState(mRegistered); mRegistered = false; mPackageMonitor.unregister(); mContext.unregisterReceiver(mBroadcastReceiver); mHandler.post(() -> onBestServiceChanged(false)); return true; } private void onBestServiceChanged(boolean forceRebind) { Preconditions.checkState(Looper.myLooper() == mHandler.getLooper()); ServiceInfo bestServiceInfo = ServiceInfo.NONE; if (mRegistered) { List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServicesAsUser( mIntent, GET_META_DATA | MATCH_DIRECT_BOOT_AUTO | MATCH_SYSTEM_ONLY, mCurrentUserId); ServiceInfo bestServiceInfo = ServiceInfo.NONE; for (ResolveInfo resolveInfo : resolveInfos) { ServiceInfo serviceInfo = new ServiceInfo(resolveInfo, mCurrentUserId); if (serviceInfo.compareTo(bestServiceInfo) > 0) { bestServiceInfo = serviceInfo; } } } if (forceRebind || !bestServiceInfo.equals(mTargetService)) { rebind(bestServiceInfo); Loading
services/core/java/com/android/server/location/GeocoderProxy.java +5 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,11 @@ public class GeocoderProxy { } private boolean register() { return mServiceWatcher.register(); boolean resolves = mServiceWatcher.checkServiceResolves(); if (resolves) { mServiceWatcher.register(); } return resolves; } /** Loading
services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java +5 −1 Original line number Diff line number Diff line Loading @@ -75,7 +75,11 @@ public class HardwareActivityRecognitionProxy { } private boolean register() { return mServiceWatcher.register(); boolean resolves = mServiceWatcher.checkServiceResolves(); if (resolves) { mServiceWatcher.register(); } return resolves; } private void onBind(IBinder binder, ComponentName service) throws RemoteException { Loading
services/core/java/com/android/server/location/ProxyLocationProvider.java +5 −1 Original line number Diff line number Diff line Loading @@ -92,7 +92,11 @@ public class ProxyLocationProvider extends AbstractLocationProvider { } private boolean register() { return mServiceWatcher.register(); boolean resolves = mServiceWatcher.checkServiceResolves(); if (resolves) { mServiceWatcher.register(); } return resolves; } private void onBind(IBinder binder, ComponentName service) throws RemoteException { Loading
services/core/java/com/android/server/location/geofence/GeofenceProxy.java +4 −4 Original line number Diff line number Diff line Loading @@ -75,16 +75,16 @@ public final class GeofenceProxy { } private boolean register(Context context) { if (mServiceWatcher.register()) { boolean resolves = mServiceWatcher.checkServiceResolves(); if (resolves) { mServiceWatcher.register(); context.bindServiceAsUser( new Intent(context, GeofenceHardwareService.class), new GeofenceProxyServiceConnection(), Context.BIND_AUTO_CREATE, UserHandle.SYSTEM); return true; } return false; return resolves; } private class GeofenceProxyServiceConnection implements ServiceConnection { Loading