Loading services/core/java/com/android/server/TEST_MAPPING +3 −5 Original line number Diff line number Diff line { "presubmit": [ { "name": "CtsLocationFineTestCases" }, { "name": "CtsLocationCoarseTestCases" }, Loading Loading @@ -66,10 +69,5 @@ ], "file_patterns": ["ClipboardService\\.java"] } ], "postsubmit": [ { "name": "CtsLocationFineTestCases" } ] } services/core/java/com/android/server/location/LocationManagerService.java +11 −1 Original line number Diff line number Diff line Loading @@ -115,6 +115,7 @@ import com.android.server.location.injector.Injector; import com.android.server.location.injector.LocationPermissionsHelper; import com.android.server.location.injector.LocationPowerSaveModeHelper; import com.android.server.location.injector.LocationUsageLogger; import com.android.server.location.injector.PackageResetHelper; import com.android.server.location.injector.ScreenInteractiveHelper; import com.android.server.location.injector.SettingsHelper; import com.android.server.location.injector.SystemAlarmHelper; Loading @@ -125,6 +126,7 @@ import com.android.server.location.injector.SystemDeviceStationaryHelper; import com.android.server.location.injector.SystemEmergencyHelper; import com.android.server.location.injector.SystemLocationPermissionsHelper; import com.android.server.location.injector.SystemLocationPowerSaveModeHelper; import com.android.server.location.injector.SystemPackageResetHelper; import com.android.server.location.injector.SystemScreenInteractiveHelper; import com.android.server.location.injector.SystemSettingsHelper; import com.android.server.location.injector.SystemUserInfoHelper; Loading Loading @@ -1696,11 +1698,13 @@ public class LocationManagerService extends ILocationManager.Stub implements private final SystemDeviceStationaryHelper mDeviceStationaryHelper; private final SystemDeviceIdleHelper mDeviceIdleHelper; private final LocationUsageLogger mLocationUsageLogger; private final PackageResetHelper mPackageResetHelper; // lazily instantiated since they may not always be used @GuardedBy("this") private @Nullable SystemEmergencyHelper mEmergencyCallHelper; @Nullable private SystemEmergencyHelper mEmergencyCallHelper; @GuardedBy("this") private boolean mSystemReady; Loading @@ -1721,6 +1725,7 @@ public class LocationManagerService extends ILocationManager.Stub implements mDeviceStationaryHelper = new SystemDeviceStationaryHelper(); mDeviceIdleHelper = new SystemDeviceIdleHelper(context); mLocationUsageLogger = new LocationUsageLogger(); mPackageResetHelper = new SystemPackageResetHelper(context); } synchronized void onSystemReady() { Loading Loading @@ -1811,5 +1816,10 @@ public class LocationManagerService extends ILocationManager.Stub implements public LocationUsageLogger getLocationUsageLogger() { return mLocationUsageLogger; } @Override public PackageResetHelper getPackageResetHelper() { return mPackageResetHelper; } } } services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java +38 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.server.LocalServices; import com.android.server.location.injector.AppForegroundHelper; import com.android.server.location.injector.Injector; import com.android.server.location.injector.LocationPermissionsHelper; import com.android.server.location.injector.PackageResetHelper; import com.android.server.location.injector.SettingsHelper; import com.android.server.location.injector.UserInfoHelper; import com.android.server.location.injector.UserInfoHelper.UserListener; Loading Loading @@ -193,6 +194,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter protected final LocationPermissionsHelper mLocationPermissionsHelper; protected final AppForegroundHelper mAppForegroundHelper; protected final LocationManagerInternal mLocationManagerInternal; private final PackageResetHelper mPackageResetHelper; private final UserListener mUserChangedListener = this::onUserChanged; private final ProviderEnabledListener mProviderEnabledChangedListener = Loading @@ -218,12 +220,25 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter }; private final AppForegroundHelper.AppForegroundListener mAppForegroundChangedListener = this::onAppForegroundChanged; private final PackageResetHelper.Responder mPackageResetResponder = new PackageResetHelper.Responder() { @Override public void onPackageReset(String packageName) { GnssListenerMultiplexer.this.onPackageReset(packageName); } @Override public boolean isResetableForPackage(String packageName) { return GnssListenerMultiplexer.this.isResetableForPackage(packageName); } }; protected GnssListenerMultiplexer(Injector injector) { mUserInfoHelper = injector.getUserInfoHelper(); mSettingsHelper = injector.getSettingsHelper(); mLocationPermissionsHelper = injector.getLocationPermissionsHelper(); mAppForegroundHelper = injector.getAppForegroundHelper(); mPackageResetHelper = injector.getPackageResetHelper(); mLocationManagerInternal = Objects.requireNonNull( LocalServices.getService(LocationManagerInternal.class)); } Loading Loading @@ -357,6 +372,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter mLocationPackageBlacklistChangedListener); mLocationPermissionsHelper.addListener(mLocationPermissionsListener); mAppForegroundHelper.addListener(mAppForegroundChangedListener); mPackageResetHelper.register(mPackageResetResponder); } @Override Loading @@ -374,6 +390,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter mLocationPackageBlacklistChangedListener); mLocationPermissionsHelper.removeListener(mLocationPermissionsListener); mAppForegroundHelper.removeListener(mAppForegroundChangedListener); mPackageResetHelper.unregister(mPackageResetResponder); } private void onUserChanged(int userId, int change) { Loading Loading @@ -407,6 +424,27 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter updateRegistrations(registration -> registration.onForegroundChanged(uid, foreground)); } private void onPackageReset(String packageName) { // invoked when a package is "force quit" - move off the main thread FgThread.getExecutor().execute( () -> updateRegistrations( registration -> { if (registration.getIdentity().getPackageName().equals( packageName)) { registration.remove(); } return false; })); } private boolean isResetableForPackage(String packageName) { // invoked to find out if the given package has any state that can be "force quit" return findRegistration( registration -> registration.getIdentity().getPackageName().equals(packageName)); } @Override protected String getServiceState() { if (!isSupported()) { Loading services/core/java/com/android/server/location/injector/Injector.java +3 −0 Original line number Diff line number Diff line Loading @@ -63,4 +63,7 @@ public interface Injector { /** Returns a LocationUsageLogger. */ LocationUsageLogger getLocationUsageLogger(); /** Returns a PackageResetHelper. */ PackageResetHelper getPackageResetHelper(); } services/core/java/com/android/server/location/injector/PackageResetHelper.java 0 → 100644 +101 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.location.injector; import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.util.concurrent.CopyOnWriteArrayList; /** Helpers for tracking queries and resets of package state. */ public abstract class PackageResetHelper { /** Interface for responding to reset events. */ public interface Responder { /** * Called when a package's runtime state is being reset for whatever reason and any * components carrying runtime state on behalf of the package should clear that state. * * @param packageName The name of the package. */ void onPackageReset(String packageName); /** * Called when the system queries whether this package has any active state for the given * package. Should return true if the component has some runtime state that is resetable of * behalf of the given package, and false otherwise. * * @param packageName The name of the package. * @return True if this component has resetable state for the given package. */ boolean isResetableForPackage(String packageName); } private final CopyOnWriteArrayList<Responder> mResponders; public PackageResetHelper() { mResponders = new CopyOnWriteArrayList<>(); } /** Begin listening for package reset events. */ public synchronized void register(Responder responder) { boolean empty = mResponders.isEmpty(); mResponders.add(responder); if (empty) { onRegister(); } } /** Stop listening for package reset events. */ public synchronized void unregister(Responder responder) { mResponders.remove(responder); if (mResponders.isEmpty()) { onUnregister(); } } @GuardedBy("this") protected abstract void onRegister(); @GuardedBy("this") protected abstract void onUnregister(); protected final void notifyPackageReset(String packageName) { if (D) { Log.d(TAG, "package " + packageName + " reset"); } for (Responder responder : mResponders) { responder.onPackageReset(packageName); } } protected final boolean queryResetableForPackage(String packageName) { for (Responder responder : mResponders) { if (responder.isResetableForPackage(packageName)) { return true; } } return false; } } Loading
services/core/java/com/android/server/TEST_MAPPING +3 −5 Original line number Diff line number Diff line { "presubmit": [ { "name": "CtsLocationFineTestCases" }, { "name": "CtsLocationCoarseTestCases" }, Loading Loading @@ -66,10 +69,5 @@ ], "file_patterns": ["ClipboardService\\.java"] } ], "postsubmit": [ { "name": "CtsLocationFineTestCases" } ] }
services/core/java/com/android/server/location/LocationManagerService.java +11 −1 Original line number Diff line number Diff line Loading @@ -115,6 +115,7 @@ import com.android.server.location.injector.Injector; import com.android.server.location.injector.LocationPermissionsHelper; import com.android.server.location.injector.LocationPowerSaveModeHelper; import com.android.server.location.injector.LocationUsageLogger; import com.android.server.location.injector.PackageResetHelper; import com.android.server.location.injector.ScreenInteractiveHelper; import com.android.server.location.injector.SettingsHelper; import com.android.server.location.injector.SystemAlarmHelper; Loading @@ -125,6 +126,7 @@ import com.android.server.location.injector.SystemDeviceStationaryHelper; import com.android.server.location.injector.SystemEmergencyHelper; import com.android.server.location.injector.SystemLocationPermissionsHelper; import com.android.server.location.injector.SystemLocationPowerSaveModeHelper; import com.android.server.location.injector.SystemPackageResetHelper; import com.android.server.location.injector.SystemScreenInteractiveHelper; import com.android.server.location.injector.SystemSettingsHelper; import com.android.server.location.injector.SystemUserInfoHelper; Loading Loading @@ -1696,11 +1698,13 @@ public class LocationManagerService extends ILocationManager.Stub implements private final SystemDeviceStationaryHelper mDeviceStationaryHelper; private final SystemDeviceIdleHelper mDeviceIdleHelper; private final LocationUsageLogger mLocationUsageLogger; private final PackageResetHelper mPackageResetHelper; // lazily instantiated since they may not always be used @GuardedBy("this") private @Nullable SystemEmergencyHelper mEmergencyCallHelper; @Nullable private SystemEmergencyHelper mEmergencyCallHelper; @GuardedBy("this") private boolean mSystemReady; Loading @@ -1721,6 +1725,7 @@ public class LocationManagerService extends ILocationManager.Stub implements mDeviceStationaryHelper = new SystemDeviceStationaryHelper(); mDeviceIdleHelper = new SystemDeviceIdleHelper(context); mLocationUsageLogger = new LocationUsageLogger(); mPackageResetHelper = new SystemPackageResetHelper(context); } synchronized void onSystemReady() { Loading Loading @@ -1811,5 +1816,10 @@ public class LocationManagerService extends ILocationManager.Stub implements public LocationUsageLogger getLocationUsageLogger() { return mLocationUsageLogger; } @Override public PackageResetHelper getPackageResetHelper() { return mPackageResetHelper; } } }
services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java +38 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.server.LocalServices; import com.android.server.location.injector.AppForegroundHelper; import com.android.server.location.injector.Injector; import com.android.server.location.injector.LocationPermissionsHelper; import com.android.server.location.injector.PackageResetHelper; import com.android.server.location.injector.SettingsHelper; import com.android.server.location.injector.UserInfoHelper; import com.android.server.location.injector.UserInfoHelper.UserListener; Loading Loading @@ -193,6 +194,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter protected final LocationPermissionsHelper mLocationPermissionsHelper; protected final AppForegroundHelper mAppForegroundHelper; protected final LocationManagerInternal mLocationManagerInternal; private final PackageResetHelper mPackageResetHelper; private final UserListener mUserChangedListener = this::onUserChanged; private final ProviderEnabledListener mProviderEnabledChangedListener = Loading @@ -218,12 +220,25 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter }; private final AppForegroundHelper.AppForegroundListener mAppForegroundChangedListener = this::onAppForegroundChanged; private final PackageResetHelper.Responder mPackageResetResponder = new PackageResetHelper.Responder() { @Override public void onPackageReset(String packageName) { GnssListenerMultiplexer.this.onPackageReset(packageName); } @Override public boolean isResetableForPackage(String packageName) { return GnssListenerMultiplexer.this.isResetableForPackage(packageName); } }; protected GnssListenerMultiplexer(Injector injector) { mUserInfoHelper = injector.getUserInfoHelper(); mSettingsHelper = injector.getSettingsHelper(); mLocationPermissionsHelper = injector.getLocationPermissionsHelper(); mAppForegroundHelper = injector.getAppForegroundHelper(); mPackageResetHelper = injector.getPackageResetHelper(); mLocationManagerInternal = Objects.requireNonNull( LocalServices.getService(LocationManagerInternal.class)); } Loading Loading @@ -357,6 +372,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter mLocationPackageBlacklistChangedListener); mLocationPermissionsHelper.addListener(mLocationPermissionsListener); mAppForegroundHelper.addListener(mAppForegroundChangedListener); mPackageResetHelper.register(mPackageResetResponder); } @Override Loading @@ -374,6 +390,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter mLocationPackageBlacklistChangedListener); mLocationPermissionsHelper.removeListener(mLocationPermissionsListener); mAppForegroundHelper.removeListener(mAppForegroundChangedListener); mPackageResetHelper.unregister(mPackageResetResponder); } private void onUserChanged(int userId, int change) { Loading Loading @@ -407,6 +424,27 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter updateRegistrations(registration -> registration.onForegroundChanged(uid, foreground)); } private void onPackageReset(String packageName) { // invoked when a package is "force quit" - move off the main thread FgThread.getExecutor().execute( () -> updateRegistrations( registration -> { if (registration.getIdentity().getPackageName().equals( packageName)) { registration.remove(); } return false; })); } private boolean isResetableForPackage(String packageName) { // invoked to find out if the given package has any state that can be "force quit" return findRegistration( registration -> registration.getIdentity().getPackageName().equals(packageName)); } @Override protected String getServiceState() { if (!isSupported()) { Loading
services/core/java/com/android/server/location/injector/Injector.java +3 −0 Original line number Diff line number Diff line Loading @@ -63,4 +63,7 @@ public interface Injector { /** Returns a LocationUsageLogger. */ LocationUsageLogger getLocationUsageLogger(); /** Returns a PackageResetHelper. */ PackageResetHelper getPackageResetHelper(); }
services/core/java/com/android/server/location/injector/PackageResetHelper.java 0 → 100644 +101 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.location.injector; import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.util.concurrent.CopyOnWriteArrayList; /** Helpers for tracking queries and resets of package state. */ public abstract class PackageResetHelper { /** Interface for responding to reset events. */ public interface Responder { /** * Called when a package's runtime state is being reset for whatever reason and any * components carrying runtime state on behalf of the package should clear that state. * * @param packageName The name of the package. */ void onPackageReset(String packageName); /** * Called when the system queries whether this package has any active state for the given * package. Should return true if the component has some runtime state that is resetable of * behalf of the given package, and false otherwise. * * @param packageName The name of the package. * @return True if this component has resetable state for the given package. */ boolean isResetableForPackage(String packageName); } private final CopyOnWriteArrayList<Responder> mResponders; public PackageResetHelper() { mResponders = new CopyOnWriteArrayList<>(); } /** Begin listening for package reset events. */ public synchronized void register(Responder responder) { boolean empty = mResponders.isEmpty(); mResponders.add(responder); if (empty) { onRegister(); } } /** Stop listening for package reset events. */ public synchronized void unregister(Responder responder) { mResponders.remove(responder); if (mResponders.isEmpty()) { onUnregister(); } } @GuardedBy("this") protected abstract void onRegister(); @GuardedBy("this") protected abstract void onUnregister(); protected final void notifyPackageReset(String packageName) { if (D) { Log.d(TAG, "package " + packageName + " reset"); } for (Responder responder : mResponders) { responder.onPackageReset(packageName); } } protected final boolean queryResetableForPackage(String packageName) { for (Responder responder : mResponders) { if (responder.isResetableForPackage(packageName)) { return true; } } return false; } }