Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f910d320 authored by destradaa's avatar destradaa Committed by Android (Google) Code Review
Browse files

Merge "Address Robin's code review comments in initial FlpHal submission." into klp-dev

parents 35786c34 64be0c61
Loading
Loading
Loading
Loading
+102 −24
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
 *
 * 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 CONDITIOS OF ANY KIND, either express or implied.
 * 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.
 */
@@ -21,20 +21,26 @@ import android.hardware.location.IFusedLocationHardwareSink;

import android.location.Location;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * Class that exposes IFusedLocationHardware functionality to unbundled services.
 * Namely this is used by GmsCore Fused Location Provider.
 */
public final class FusedLocationHardware {
    private final String TAG = "FusedLocationHardware";

    private IFusedLocationHardware mLocationHardware;
    ArrayList<FusedLocationHardwareSink> mSinkList = new ArrayList<FusedLocationHardwareSink>();

    // the list uses a copy-on-write pattern to update its contents
    HashMap<FusedLocationHardwareSink, DispatcherHandler> mSinkList =
            new HashMap<FusedLocationHardwareSink, DispatcherHandler>();

    private IFusedLocationHardwareSink mInternalSink = new IFusedLocationHardwareSink.Stub() {
        @Override
@@ -48,6 +54,9 @@ public final class FusedLocationHardware {
        }
    };

    /**
     * @hide
     */
    public FusedLocationHardware(IFusedLocationHardware locationHardware) {
        mLocationHardware = locationHardware;
    }
@@ -55,19 +64,24 @@ public final class FusedLocationHardware {
    /*
     * Methods to provide a Facade for IFusedLocationHardware
     */
    public void registerSink(FusedLocationHardwareSink sink) {
        if(sink == null) {
            return;
    public void registerSink(FusedLocationHardwareSink sink, Looper looper) {
        if(sink == null || looper == null) {
            throw new IllegalArgumentException("Parameter sink and looper cannot be null.");
        }

        boolean registerSink = false;
        boolean registerSink;
        synchronized (mSinkList) {
            // register only on first insertion
            registerSink = mSinkList.size() == 0;
            // guarantee uniqueness
            if(!mSinkList.contains(sink)) {
                mSinkList.add(sink);
            if(mSinkList.containsKey(sink)) {
                return;
            }

            HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList =
                    new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList);
            newSinkList.put(sink, new DispatcherHandler(looper));
            mSinkList = newSinkList;
        }

        if(registerSink) {
@@ -81,14 +95,23 @@ public final class FusedLocationHardware {

    public void unregisterSink(FusedLocationHardwareSink sink) {
        if(sink == null) {
            return;
            throw new IllegalArgumentException("Parameter sink cannot be null.");
        }

        boolean unregisterSink = false;
        boolean unregisterSink;
        synchronized(mSinkList) {
            mSinkList.remove(sink);
            if(!mSinkList.containsKey(sink)) {
                //done
                return;
            }

            HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList =
                    new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList);
            newSinkList.remove(sink);
            //unregister after the last sink
            unregisterSink = mSinkList.size() == 0;
            unregisterSink = newSinkList.size() == 0;

            mSinkList = newSinkList;
        }

        if(unregisterSink) {
@@ -176,27 +199,82 @@ public final class FusedLocationHardware {
    }

    /*
     * Helper methods
     * Helper methods and classes
     */
    private class DispatcherHandler extends Handler {
        public static final int DISPATCH_LOCATION = 1;
        public static final int DISPATCH_DIAGNOSTIC_DATA = 2;

        public DispatcherHandler(Looper looper) {
            super(looper, null /*callback*/ , true /*async*/);
        }

        @Override
        public void handleMessage(Message message) {
            MessageCommand command = (MessageCommand) message.obj;
            switch(message.what) {
                case DISPATCH_LOCATION:
                    command.dispatchLocation();
                    break;
                case DISPATCH_DIAGNOSTIC_DATA:
                    command.dispatchDiagnosticData();
                default:
                    Log.e(TAG, "Invalid dispatch message");
                    break;
            }
        }
    }

    private class MessageCommand {
        private final FusedLocationHardwareSink mSink;
        private final Location[] mLocations;
        private final String mData;

        public MessageCommand(
                FusedLocationHardwareSink sink,
                Location[] locations,
                String data) {
            mSink = sink;
            mLocations = locations;
            mData = data;
        }

        public void dispatchLocation() {
            mSink.onLocationAvailable(mLocations);
        }

        public void dispatchDiagnosticData() {
            mSink.onDiagnosticDataAvailable(mData);
        }
    }

    private void dispatchLocations(Location[] locations) {
        ArrayList<FusedLocationHardwareSink> sinks = null;
        HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks;
        synchronized (mSinkList) {
            sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList);
            sinks = mSinkList;
        }

        for(FusedLocationHardwareSink sink : sinks) {
            sink.onLocationAvailable(locations);
        for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) {
            Message message = Message.obtain(
                    entry.getValue(),
                    DispatcherHandler.DISPATCH_LOCATION,
                    new MessageCommand(entry.getKey(), locations, null /*data*/));
            message.sendToTarget();
        }
    }

    private void dispatchDiagnosticData(String data) {
        ArrayList<FusedLocationHardwareSink> sinks = null;
        HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks;
        synchronized(mSinkList) {
            sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList);
            sinks = mSinkList;
        }

        for(FusedLocationHardwareSink sink : sinks) {
            sink.onDiagnosticDataAvailable(data);
        for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) {
            Message message = Message.obtain(
                    entry.getValue(),
                    DispatcherHandler.DISPATCH_DIAGNOSTIC_DATA,
                    new MessageCommand(entry.getKey(), null /*locations*/, data));
            message.sendToTarget();
        }
    }
}
+0 −1
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.location.Location;

/**
 * Base class for sinks to interact with FusedLocationHardware.
 * This is mainly used by GmsCore Fused Provider.
 */
public abstract class FusedLocationHardwareSink {
    /*
+0 −2
Original line number Diff line number Diff line
@@ -28,8 +28,6 @@ import android.os.IBinder;
 *
 * <p>IMPORTANT: This class is effectively a public API for unbundled applications, and must remain
 * API stable. See README.txt in the root of this package for more information.
 *
 * @hide
 */
public abstract class FusedProvider {
    private IFusedProvider.Stub mProvider = new IFusedProvider.Stub() {
+4 −1
Original line number Diff line number Diff line
@@ -437,7 +437,10 @@ public class LocationManagerService extends ILocationManager.Stub {
        FusedProxy fusedProxy = FusedProxy.createAndBind(
                mContext,
                mLocationHandler,
                flpHardwareProvider.getLocationHardware());
                flpHardwareProvider.getLocationHardware(),
                com.android.internal.R.bool.config_enableFusedLocationOverlay,
                com.android.internal.R.string.config_fusedLocationProviderPackageName,
                com.android.internal.R.array.config_locationProviderPackageNames);

        if(fusedProxy == null) {
            Slog.e(TAG, "No FusedProvider found.");
+27 −15
Original line number Diff line number Diff line
@@ -28,11 +28,10 @@ import android.location.LocationManager;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.util.Slog;

/**
 * This class is an interop layer for JVM types and the JNI code that interacts
@@ -48,6 +47,7 @@ public class FlpHardwareProvider {

    private final static String TAG = "FlpHardwareProvider";
    private final Context mContext;
    private final Object mLocationSinkLock = new Object();

    public static FlpHardwareProvider getInstance(Context context) {
        if (sSingletonInstance == null) {
@@ -61,7 +61,6 @@ public class FlpHardwareProvider {
        mContext = context;

        // register for listening for passive provider data
        Handler handler = new Handler();
        LocationManager manager = (LocationManager) mContext.getSystemService(
                Context.LOCATION_SERVICE);
        manager.requestLocationUpdates(
@@ -69,7 +68,7 @@ public class FlpHardwareProvider {
                0 /* minTime */,
                0 /* minDistance */,
                new NetworkLocationListener(),
                handler.getLooper());
                Looper.myLooper());
    }

    public static boolean isSupported() {
@@ -87,9 +86,13 @@ public class FlpHardwareProvider {
            location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
        }

        IFusedLocationHardwareSink sink;
        synchronized (mLocationSinkLock) {
            sink = mLocationSink;
        }
        try {
            if (mLocationSink != null) {
                mLocationSink.onLocationAvailable(locations);
            if (sink != null) {
                sink.onLocationAvailable(locations);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException calling onLocationAvailable");
@@ -98,9 +101,13 @@ public class FlpHardwareProvider {

    // FlpDiagnosticCallbacks members
    private void onDataReport(String data) {
        IFusedLocationHardwareSink sink;
        synchronized (mLocationSinkLock) {
            sink = mLocationSink;
        }
        try {
            if (mLocationSink != null) {
                mLocationSink.onDiagnosticDataAvailable(data);
                sink.onDiagnosticDataAvailable(data);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException calling onDiagnosticDataAvailable");
@@ -199,21 +206,26 @@ public class FlpHardwareProvider {
    private final IFusedLocationHardware mLocationHardware = new IFusedLocationHardware.Stub() {
        @Override
        public void registerSink(IFusedLocationHardwareSink eventSink) {
            synchronized (mLocationSinkLock) {
                // only one sink is allowed at the moment
                if (mLocationSink != null) {
                throw new RuntimeException("IFusedLocationHardware does not support multiple sinks");
                    throw new RuntimeException(
                            "IFusedLocationHardware does not support multiple sinks");
                }

                mLocationSink = eventSink;
            }
        }

        @Override
        public void unregisterSink(IFusedLocationHardwareSink eventSink) {
            synchronized (mLocationSinkLock) {
                // don't throw if the sink is not registered, simply make it a no-op
                if (mLocationSink == eventSink) {
                    mLocationSink = null;
                }
            }
        }

        @Override
        public int getSupportedBatchSize() {
Loading