Merge "Add location shared library for location provider APIs." into gingerbread
diff --git a/location/Android.mk b/location/Android.mk
new file mode 100644
index 0000000..12db2f7
--- /dev/null
+++ b/location/Android.mk
@@ -0,0 +1,19 @@
+# Copyright (C) 2010 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.
+
+LOCAL_PATH := $(call my-dir)
+
+ifeq ($(TARGET_BUILD_APPS),)
+include $(call all-makefiles-under, $(LOCAL_PATH))
+endif
diff --git a/location/lib/Android.mk b/location/lib/Android.mk
new file mode 100644
index 0000000..a06478a
--- /dev/null
+++ b/location/lib/Android.mk
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2010 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+# the library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= com.android.location.provider
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+            $(call all-subdir-java-files)
+
+include $(BUILD_JAVA_LIBRARY)
+
+
+# ====  com.google.location.xml lib def  ========================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := com.android.location.provider.xml
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_CLASS := ETC
+
+# This will install the file in /system/etc/permissions
+#
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
diff --git a/location/lib/com.android.location.provider.xml b/location/lib/com.android.location.provider.xml
new file mode 100644
index 0000000..000e68f
--- /dev/null
+++ b/location/lib/com.android.location.provider.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<permissions>
+    <library name="com.android.location.provider"
+            file="/system/framework/com.android.location.provider.jar" />
+</permissions>
diff --git a/location/lib/java/com/android/location/provider/GeocodeProvider.java b/location/lib/java/com/android/location/provider/GeocodeProvider.java
new file mode 100644
index 0000000..666bb02
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/GeocodeProvider.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 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.location.provider;
+
+import android.os.IBinder;
+
+import android.location.Address;
+import android.location.GeocoderParams;
+import android.location.IGeocodeProvider;
+
+import java.util.List;
+
+/**
+ * An abstract superclass for geocode providers that are implemented
+ * outside of the core android platform.
+ * Geocode providers can be implemented as services and return the result of
+ * {@link GeocodeProvider#getBinder()} in its getBinder() method.
+ *
+ * @hide
+ */
+public abstract class GeocodeProvider {
+
+    private IGeocodeProvider.Stub mProvider = new IGeocodeProvider.Stub() {
+        public String getFromLocation(double latitude, double longitude, int maxResults,
+                GeocoderParams params, List<Address> addrs) {
+            return GeocodeProvider.this.onGetFromLocation(latitude, longitude, maxResults,
+                    params, addrs);
+        }
+
+        public String getFromLocationName(String locationName,
+                double lowerLeftLatitude, double lowerLeftLongitude,
+                double upperRightLatitude, double upperRightLongitude, int maxResults,
+                GeocoderParams params, List<Address> addrs) {
+            return GeocodeProvider.this.onGetFromLocationName(locationName, lowerLeftLatitude,
+                    lowerLeftLongitude, upperRightLatitude, upperRightLongitude,
+                    maxResults, params, addrs);
+        }
+    };
+
+    /**
+     * This method is overridden to implement the
+     * {@link android.location.Geocoder#getFromLocation(double, double, int)} method.
+     * Classes implementing this method should not hold a reference to the params parameter.
+     */
+    public abstract String onGetFromLocation(double latitude, double longitude, int maxResults,
+            GeocoderParams params, List<Address> addrs);
+
+    /**
+     * This method is overridden to implement the
+     * {@link android.location.Geocoder#getFromLocationName(String, int, double, double, double, double)} method.
+     * Classes implementing this method should not hold a reference to the params parameter.
+     */
+    public abstract String onGetFromLocationName(String locationName,
+            double lowerLeftLatitude, double lowerLeftLongitude,
+            double upperRightLatitude, double upperRightLongitude, int maxResults,
+            GeocoderParams params, List<Address> addrs);
+
+    /**
+     * Returns the Binder interface for the geocode provider.
+     * This is intended to be used for the onBind() method of
+     * a service that implements a geocoder service.
+     *
+     * @return the IBinder instance for the provider
+     */
+    public IBinder getBinder() {
+        return mProvider;
+    }
+}
diff --git a/location/lib/java/com/android/location/provider/LocationProvider.java b/location/lib/java/com/android/location/provider/LocationProvider.java
new file mode 100644
index 0000000..3714f40
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/LocationProvider.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2010 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.location.provider;
+
+import android.content.Context;
+import android.net.NetworkInfo;
+import android.location.Criteria;
+import android.location.ILocationManager;
+import android.location.ILocationProvider;
+import android.location.Location;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.WorkSource;
+import android.util.Log;
+
+/**
+ * An abstract superclass for location providers that are implemented
+ * outside of the core android platform.
+ * Location providers can be implemented as services and return the result of
+ * {@link LocationProvider#getBinder()} in its getBinder() method.
+ *
+ * @hide
+ */
+public abstract class LocationProvider {
+
+    private static final String TAG = "LocationProvider";
+
+    private ILocationManager mLocationManager;
+
+    private ILocationProvider.Stub mProvider = new ILocationProvider.Stub() {
+
+        public boolean requiresNetwork() {
+            return LocationProvider.this.onRequiresNetwork();
+        }
+
+        public boolean requiresSatellite() {
+            return LocationProvider.this.onRequiresSatellite();
+        }
+
+        public boolean requiresCell() {
+            return LocationProvider.this.onRequiresCell();
+        }
+
+        public boolean hasMonetaryCost() {
+            return LocationProvider.this.onHasMonetaryCost();
+        }
+
+        public boolean supportsAltitude() {
+            return LocationProvider.this.onSupportsAltitude();
+        }
+
+        public boolean supportsSpeed() {
+            return LocationProvider.this.onSupportsSpeed();
+        }
+
+        public boolean supportsBearing() {
+            return LocationProvider.this.onSupportsBearing();
+        }
+
+        public int getPowerRequirement() {
+            return LocationProvider.this.onGetPowerRequirement();
+        }
+
+        public boolean meetsCriteria(Criteria criteria) {
+            return LocationProvider.this.onMeetsCriteria(criteria);
+        }
+
+        public int getAccuracy() {
+            return LocationProvider.this.onGetAccuracy();
+        }
+
+        public void enable() {
+            LocationProvider.this.onEnable();
+        }
+
+        public void disable() {
+            LocationProvider.this.onDisable();
+        }
+
+        public int getStatus(Bundle extras) {
+            return LocationProvider.this.onGetStatus(extras);
+        }
+
+        public long getStatusUpdateTime() {
+            return LocationProvider.this.onGetStatusUpdateTime();
+        }
+
+        public String getInternalState() {
+            return LocationProvider.this.onGetInternalState();
+        }
+
+        public void enableLocationTracking(boolean enable) {
+            LocationProvider.this.onEnableLocationTracking(enable);
+        }
+
+        public void setMinTime(long minTime, WorkSource ws) {
+            LocationProvider.this.onSetMinTime(minTime, ws);
+        }
+
+        public void updateNetworkState(int state, NetworkInfo info) {
+            LocationProvider.this.onUpdateNetworkState(state, info);
+        }
+
+        public void updateLocation(Location location) {
+            LocationProvider.this.onUpdateLocation(location);
+        }
+
+        public boolean sendExtraCommand(String command, Bundle extras) {
+            return LocationProvider.this.onSendExtraCommand(command, extras);
+        }
+
+        public void addListener(int uid) {
+            LocationProvider.this.onAddListener(uid, new WorkSource(uid));
+        }
+
+        public void removeListener(int uid) {
+            LocationProvider.this.onRemoveListener(uid, new WorkSource(uid));
+        }
+    };
+
+    public LocationProvider() {
+        IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
+        mLocationManager = ILocationManager.Stub.asInterface(b);
+    }
+
+    /**
+     * {@hide}
+     */
+    /* package */ ILocationProvider getInterface() {
+        return mProvider;
+    }
+
+    /**
+     * Returns the Binder interface for the location provider.
+     * This is intended to be used for the onBind() method of
+     * a service that implements a location provider service.
+     *
+     * @return the IBinder instance for the provider
+     */
+    public IBinder getBinder() {
+        return mProvider;
+    }
+
+    /**
+     * Used by the location provider to report new locations.
+     *
+     * @param location new Location to report
+     *
+     * Requires the android.permission.INSTALL_LOCATION_PROVIDER permission.
+     */
+    public void reportLocation(Location location) {
+        try {
+            mLocationManager.reportLocation(location, false);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in reportLocation: ", e);
+        }
+    }
+
+    /**
+     * Returns true if the provider requires access to a
+     * data network (e.g., the Internet), false otherwise.
+     */
+    public abstract boolean onRequiresNetwork();
+
+    /**
+     * Returns true if the provider requires access to a
+     * satellite-based positioning system (e.g., GPS), false
+     * otherwise.
+     */
+    public abstract boolean onRequiresSatellite();
+
+    /**
+     * Returns true if the provider requires access to an appropriate
+     * cellular network (e.g., to make use of cell tower IDs), false
+     * otherwise.
+     */
+    public abstract boolean onRequiresCell();
+
+    /**
+     * Returns true if the use of this provider may result in a
+     * monetary charge to the user, false if use is free.  It is up to
+     * each provider to give accurate information.
+     */
+    public abstract boolean onHasMonetaryCost();
+
+    /**
+     * Returns true if the provider is able to provide altitude
+     * information, false otherwise.  A provider that reports altitude
+     * under most circumstances but may occassionally not report it
+     * should return true.
+     */
+    public abstract boolean onSupportsAltitude();
+
+    /**
+     * Returns true if the provider is able to provide speed
+     * information, false otherwise.  A provider that reports speed
+     * under most circumstances but may occassionally not report it
+     * should return true.
+     */
+    public abstract boolean onSupportsSpeed();
+
+    /**
+     * Returns true if the provider is able to provide bearing
+     * information, false otherwise.  A provider that reports bearing
+     * under most circumstances but may occassionally not report it
+     * should return true.
+     */
+    public abstract boolean onSupportsBearing();
+
+    /**
+     * Returns the power requirement for this provider.
+     *
+     * @return the power requirement for this provider, as one of the
+     * constants Criteria.POWER_REQUIREMENT_*.
+     */
+    public abstract int onGetPowerRequirement();
+
+    /**
+     * Returns true if this provider meets the given criteria,
+     * false otherwise.
+     */
+    public abstract boolean onMeetsCriteria(Criteria criteria);
+
+    /**
+     * Returns a constant describing horizontal accuracy of this provider.
+     * If the provider returns finer grain or exact location,
+     * {@link Criteria#ACCURACY_FINE} is returned, otherwise if the
+     * location is only approximate then {@link Criteria#ACCURACY_COARSE}
+     * is returned.
+     */
+    public abstract int onGetAccuracy();
+
+    /**
+     * Enables the location provider
+     */
+    public abstract void onEnable();
+
+    /**
+     * Disables the location provider
+     */
+    public abstract void onDisable();
+
+    /**
+     * Returns a information on the status of this provider.
+     * {@link android.location.LocationProvider#OUT_OF_SERVICE} is returned if the provider is
+     * out of service, and this is not expected to change in the near
+     * future; {@link android.location.LocationProvider#TEMPORARILY_UNAVAILABLE} is returned if
+     * the provider is temporarily unavailable but is expected to be
+     * available shortly; and {@link android.location.LocationProvider#AVAILABLE} is returned
+     * if the provider is currently available.
+     *
+     * <p> If extras is non-null, additional status information may be
+     * added to it in the form of provider-specific key/value pairs.
+     */
+    public abstract int onGetStatus(Bundle extras);
+
+    /**
+     * Returns the time at which the status was last updated. It is the
+     * responsibility of the provider to appropriately set this value using
+     * {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()}.
+     * there is a status update that it wishes to broadcast to all its
+     * listeners. The provider should be careful not to broadcast
+     * the same status again.
+     *
+     * @return time of last status update in millis since last reboot
+     */
+    public abstract long onGetStatusUpdateTime();
+
+    /**
+     * Returns debugging information about the location provider.
+     *
+     * @return string describing the internal state of the location provider, or null.
+     */
+    public abstract String onGetInternalState();
+
+    /**
+     * Notifies the location provider that clients are listening for locations.
+     * Called with enable set to true when the first client is added and
+     * called with enable set to false when the last client is removed.
+     * This allows the provider to prepare for receiving locations,
+     * and to shut down when no clients are remaining.
+     *
+     * @param enable true if location tracking should be enabled.
+     */
+    public abstract void onEnableLocationTracking(boolean enable);
+
+    /**
+     * Notifies the location provider of the smallest minimum time between updates amongst
+     * all clients that are listening for locations.  This allows the provider to reduce
+     * the frequency of updates to match the requested frequency.
+     *
+     * @param minTime the smallest minTime value over all listeners for this provider.
+     * @param ws the source this work is coming from.
+     */
+    public abstract void onSetMinTime(long minTime, WorkSource ws);
+
+    /**
+     * Updates the network state for the given provider. This function must
+     * be overwritten if {@link android.location.LocationProvider#requiresNetwork} returns true.
+     * The state is {@link android.location.LocationProvider#TEMPORARILY_UNAVAILABLE} (disconnected)
+     * OR {@link android.location.LocationProvider#AVAILABLE} (connected or connecting).
+     *
+     * @param state data state
+     */
+    public abstract void onUpdateNetworkState(int state, NetworkInfo info);
+
+    /**
+     * Informs the provider when a new location has been computed by a different
+     * location provider.  This is intended to be used as aiding data for the
+     * receiving provider.
+     *
+     * @param location new location from other location provider
+     */
+    public abstract void onUpdateLocation(Location location);
+
+    /**
+     * Implements addditional location provider specific additional commands.
+     *
+     * @param command name of the command to send to the provider.
+     * @param extras optional arguments for the command (or null).
+     * The provider may optionally fill the extras Bundle with results from the command.
+     *
+     * @return true if the command succeeds.
+     */
+    public abstract boolean onSendExtraCommand(String command, Bundle extras);
+
+    /**
+     * Notifies the location provider when a new client is listening for locations.
+     *
+     * @param uid user ID of the new client.
+     * @param ws a WorkSource representation of the client.
+     */
+    public abstract void onAddListener(int uid, WorkSource ws);
+
+    /**
+     * Notifies the location provider when a client is no longer listening for locations.
+     *
+     * @param uid user ID of the client no longer listening.
+     * @param ws a WorkSource representation of the client.
+     */
+    public abstract void onRemoveListener(int uid, WorkSource ws);
+}