privatelocation icon indicating copy to clipboard operation
privatelocation copied to clipboard

LocationManager.addTestLocation fails with IllegalArgumentException

Open derMart opened this issue 5 years ago • 0 comments

Hi,

using Lineageos 17.1 (Andoid 10), the app fails when location is set after the first time with the following Exception:

java.lang.IllegalArgumentException: Provider "network" already exists
2020-08-13 19:21:18.466 2451-2451/com.wesaphzt.privatelocation W/System.err:     at android.os.Parcel.createException(Parcel.java:2075)
2020-08-13 19:21:18.466 2451-2451/com.wesaphzt.privatelocation W/System.err:     at android.os.Parcel.readException(Parcel.java:2039)
2020-08-13 19:21:18.466 2451-2451/com.wesaphzt.privatelocation W/System.err:     at android.os.Parcel.readException(Parcel.java:1987)
2020-08-13 19:21:18.466 2451-2451/com.wesaphzt.privatelocation W/System.err:     at android.location.ILocationManager$Stub$Proxy.addTestProvider(ILocationManager.java:2022)
2020-08-13 19:21:18.466 2451-2451/com.wesaphzt.privatelocation W/System.err:     at android.location.LocationManager.addTestProvider(LocationManager.java:1461)
2020-08-13 19:21:18.466 2451-2451/com.wesaphzt.privatelocation W/System.err:     at com.wesaphzt.privatelocation.service.LocationProvider.<init>(LocationProvider.java:42)
2020-08-13 19:21:18.466 2451-2451/com.wesaphzt.privatelocation W/System.err:     at com.wesaphzt.privatelocation.service.LocationService.pushLocation(LocationService.java:188)
2020-08-13 19:21:18.466 2451-2451/com.wesaphzt.privatelocation W/System.err:     at com.wesaphzt.privatelocation.service.LocationService.onStartCommand(LocationService.java:78)

This is due to the implementation of frameworks/base/services/core/java/com/android/server/LocationManagerService.java of the android framework:

    @Override
    public void addTestProvider(String name, ProviderProperties properties, String opPackageName) {
        if (!canCallerAccessMockLocation(opPackageName)) {
            return;
        }

        if (PASSIVE_PROVIDER.equals(name)) {
            throw new IllegalArgumentException("Cannot mock the passive location provider");
        }

        synchronized (mLock) {
            long identity = Binder.clearCallingIdentity();
            try {
                LocationProvider oldProvider = getLocationProviderLocked(name);
                if (oldProvider != null) {
                    if (oldProvider.isMock()) {
                        throw new IllegalArgumentException(
                                "Provider \"" + name + "\" already exists");
                    }

                    removeProviderLocked(oldProvider);
                }

as can be seen, an IllegalArgumentException is thrown if the existing provider with the given name is already a test provider. This is contrary to the Android API docs which states:

Creates a test location provider and adds it to the set of active providers. This provider will replace any provider with the same name that exists prior to this call.

and does not list that the exception is thrown in the above case. Will provide a pull request to fix this shortly.

EDIT: Quote .addTestProvider source instead of .removeTestProvider

derMart avatar Aug 13 '20 17:08 derMart