Merge "Clean up interface between LocationManagerService and the location providers:"
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 628cb6b7..8c24ee1 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -22,7 +22,6 @@
 import android.location.IGeocodeProvider;
 import android.location.IGpsStatusListener;
 import android.location.ILocationListener;
-import android.location.ILocationProvider;
 import android.location.Location;
 import android.os.Bundle;
 
diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/android/location/ILocationProvider.aidl
index 9fe6ab4..5529b11 100644
--- a/location/java/android/location/ILocationProvider.aidl
+++ b/location/java/android/location/ILocationProvider.aidl
@@ -21,7 +21,7 @@
 import android.os.Bundle;
 
 /**
- * Binder interface for location providers.
+ * Binder interface for services that implement location providers.
  *
  * {@hide}
  */
diff --git a/location/java/android/location/LocationProviderInterface.java b/location/java/android/location/LocationProviderInterface.java
new file mode 100644
index 0000000..98beffe
--- /dev/null
+++ b/location/java/android/location/LocationProviderInterface.java
@@ -0,0 +1,51 @@
+/*
+ * 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 android.location;
+
+import android.location.Location;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+
+/**
+ * Location Manager's interface for location providers.
+ *
+ * {@hide}
+ */
+public interface LocationProviderInterface {
+    String getName();
+    boolean requiresNetwork();
+    boolean requiresSatellite();
+    boolean requiresCell();
+    boolean hasMonetaryCost();
+    boolean supportsAltitude();
+    boolean supportsSpeed();
+    boolean supportsBearing();
+    int getPowerRequirement();
+    int getAccuracy();
+    boolean isEnabled();
+    void enable();
+    void disable();
+    int getStatus(Bundle extras);
+    long getStatusUpdateTime();
+    void enableLocationTracking(boolean enable);
+    void setMinTime(long minTime);
+    void updateNetworkState(int state, NetworkInfo info);
+    void updateLocation(Location location);
+    boolean sendExtraCommand(String command, Bundle extras);
+    void addListener(int uid);
+    void removeListener(int uid);
+}
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 8b5f702..dce3b27 100755
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -26,11 +26,11 @@
 import android.location.IGpsStatusListener;
 import android.location.IGpsStatusProvider;
 import android.location.ILocationManager;
-import android.location.ILocationProvider;
 import android.location.INetInitiatedListener;
 import android.location.Location;
 import android.location.LocationManager;
 import android.location.LocationProvider;
+import android.location.LocationProviderInterface;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.SntpClient;
@@ -65,7 +65,7 @@
  *
  * {@hide}
  */
-public class GpsLocationProvider extends ILocationProvider.Stub {
+public class GpsLocationProvider implements LocationProviderInterface {
 
     private static final String TAG = "GpsLocationProvider";
 
@@ -374,6 +374,13 @@
     }
 
     /**
+     * Returns the name of this provider.
+     */
+    public String getName() {
+        return LocationManager.GPS_PROVIDER;
+    }
+
+    /**
      * Returns true if the provider requires access to a
      * data network (e.g., the Internet), false otherwise.
      */
@@ -576,6 +583,10 @@
         }
     }
 
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
     public int getStatus(Bundle extras) {
         if (extras != null) {
             extras.putInt("satellites", mSvCount);
diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java
index 361104f..abb90b7 100644
--- a/location/java/com/android/internal/location/LocationProviderProxy.java
+++ b/location/java/com/android/internal/location/LocationProviderProxy.java
@@ -22,6 +22,7 @@
 import android.content.ServiceConnection;
 import android.location.ILocationProvider;
 import android.location.Location;
+import android.location.LocationProviderInterface;
 import android.net.NetworkInfo;
 import android.os.Bundle;
 import android.os.Handler;
@@ -31,18 +32,17 @@
 import android.util.Log;
 
 /**
- * A class for proxying ILocationProvider implementations.
+ * A class for proxying location providers implemented as services.
  *
  * {@hide}
  */
-public class LocationProviderProxy {
+public class LocationProviderProxy implements LocationProviderInterface {
 
     private static final String TAG = "LocationProviderProxy";
 
     private final Context mContext;
     private final String mName;
     private ILocationProvider mProvider;
-    private Intent mIntent;
     private Handler mHandler;
     private final Connection mServiceConnection = new Connection();
 
@@ -56,21 +56,13 @@
     // for caching requiresNetwork, requiresSatellite, etc.
     private DummyLocationProvider mCachedAttributes;
 
-    // constructor for proxying built-in location providers
-    public LocationProviderProxy(Context context, String name, ILocationProvider provider) {
-        mContext = context;
-        mName = name;
-        mProvider = provider;
-    }
-
     // constructor for proxying location providers implemented in a separate service
     public LocationProviderProxy(Context context, String name, String serviceName,
             Handler handler) {
         mContext = context;
         mName = name;
-        mIntent = new Intent(serviceName);
         mHandler = handler;
-        mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+        mContext.bindService(new Intent(serviceName), mServiceConnection, Context.BIND_AUTO_CREATE);
     }
 
     private class Connection implements ServiceConnection {
diff --git a/location/java/com/android/internal/location/MockProvider.java b/location/java/com/android/internal/location/MockProvider.java
index 7d9e86c..2f6fdee 100644
--- a/location/java/com/android/internal/location/MockProvider.java
+++ b/location/java/com/android/internal/location/MockProvider.java
@@ -17,9 +17,9 @@
 package com.android.internal.location;
 
 import android.location.ILocationManager;
-import android.location.ILocationProvider;
 import android.location.Location;
 import android.location.LocationProvider;
+import android.location.LocationProviderInterface;
 import android.net.NetworkInfo;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -33,7 +33,7 @@
  *
  * {@hide}
  */
-public class MockProvider extends ILocationProvider.Stub {
+public class MockProvider implements LocationProviderInterface {
     private final String mName;
     private final ILocationManager mLocationManager;
     private final boolean mRequiresNetwork;
@@ -73,6 +73,10 @@
         mLocation = new Location(name);
     }
 
+    public String getName() {
+        return mName;
+    }
+
     public void disable() {
         mEnabled = false;
     }
@@ -81,6 +85,10 @@
         mEnabled = true;
     }
 
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
     public int getStatus(Bundle extras) {
         if (mHasStatus) {
             extras.clear();
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index fff6c54..e12f2e1 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -45,11 +45,11 @@
 import android.location.IGpsStatusProvider;
 import android.location.ILocationListener;
 import android.location.ILocationManager;
-import android.location.ILocationProvider;
 import android.location.INetInitiatedListener;
 import android.location.Location;
 import android.location.LocationManager;
 import android.location.LocationProvider;
+import android.location.LocationProviderInterface;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.Uri;
@@ -114,8 +114,8 @@
     private LocationWorkerHandler mLocationHandler;
 
     // Cache the real providers for use in addTestProvider() and removeTestProvider()
-     LocationProviderProxy mNetworkLocationProvider;
-     LocationProviderProxy mGpsLocationProvider;
+     LocationProviderInterface mNetworkLocationProvider;
+     LocationProviderInterface mGpsLocationProvider;
 
     // Handler messages
     private static final int MESSAGE_LOCATION_CHANGED = 1;
@@ -134,10 +134,10 @@
     /**
      * List of location providers.
      */
-    private final ArrayList<LocationProviderProxy> mProviders =
-        new ArrayList<LocationProviderProxy>();
-    private final HashMap<String, LocationProviderProxy> mProvidersByName
-        = new HashMap<String, LocationProviderProxy>();
+    private final ArrayList<LocationProviderInterface> mProviders =
+        new ArrayList<LocationProviderInterface>();
+    private final HashMap<String, LocationProviderInterface> mProvidersByName
+        = new HashMap<String, LocationProviderInterface>();
 
     /**
      * Object used internally for synchronization
@@ -411,12 +411,12 @@
         }
     }
 
-    private void addProvider(LocationProviderProxy provider) {
+    private void addProvider(LocationProviderInterface provider) {
         mProviders.add(provider);
         mProvidersByName.put(provider.getName(), provider);
     }
 
-    private void removeProvider(LocationProviderProxy provider) {
+    private void removeProvider(LocationProviderInterface provider) {
         mProviders.remove(provider);
         mProvidersByName.remove(provider.getName());
     }
@@ -445,13 +445,11 @@
         // Attempt to load "real" providers first
         if (GpsLocationProvider.isSupported()) {
             // Create a gps location provider
-            GpsLocationProvider provider = new GpsLocationProvider(mContext, this);
-            mGpsStatusProvider = provider.getGpsStatusProvider();
-            mNetInitiatedListener = provider.getNetInitiatedListener();
-            LocationProviderProxy proxy =
-                    new LocationProviderProxy(mContext, LocationManager.GPS_PROVIDER, provider);
-            addProvider(proxy);
-            mGpsLocationProvider = proxy;
+            GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
+            mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
+            mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
+            addProvider(gpsProvider);
+            mGpsLocationProvider = gpsProvider;
         }
 
         // initialize external network location and geocoder services
@@ -591,7 +589,7 @@
         }
         ArrayList<String> out = new ArrayList<String>(mProviders.size());
         for (int i = mProviders.size() - 1; i >= 0; i--) {
-            LocationProviderProxy p = mProviders.get(i);
+            LocationProviderInterface p = mProviders.get(i);
             out.add(p.getName());
         }
         return out;
@@ -616,7 +614,7 @@
         }
         ArrayList<String> out = new ArrayList<String>(mProviders.size());
         for (int i = mProviders.size() - 1; i >= 0; i--) {
-            LocationProviderProxy p = mProviders.get(i);
+            LocationProviderInterface p = mProviders.get(i);
             String name = p.getName();
             if (isAllowedProviderSafe(name)) {
                 if (enabledOnly && !isAllowedBySettingsLocked(name)) {
@@ -630,7 +628,7 @@
 
     private void updateProvidersLocked() {
         for (int i = mProviders.size() - 1; i >= 0; i--) {
-            LocationProviderProxy p = mProviders.get(i);
+            LocationProviderInterface p = mProviders.get(i);
             boolean isEnabled = p.isEnabled();
             String name = p.getName();
             boolean shouldBeEnabled = isAllowedBySettingsLocked(name);
@@ -647,7 +645,7 @@
     private void updateProviderListenersLocked(String provider, boolean enabled) {
         int listeners = 0;
 
-        LocationProviderProxy p = mProvidersByName.get(provider);
+        LocationProviderInterface p = mProvidersByName.get(provider);
         if (p == null) {
             return;
         }
@@ -837,8 +835,8 @@
             Log.v(TAG, "_requestLocationUpdates: listener = " + receiver);
         }
 
-        LocationProviderProxy proxy = mProvidersByName.get(provider);
-        if (proxy == null) {
+        LocationProviderInterface p = mProvidersByName.get(provider);
+        if (p == null) {
             throw new IllegalArgumentException("provider=" + provider);
         }
 
@@ -856,14 +854,14 @@
             }
 
             if (newUid) {
-                proxy.addListener(callingUid);
+                p.addListener(callingUid);
             }
 
             boolean isProviderEnabled = isAllowedBySettingsLocked(provider);
             if (isProviderEnabled) {
                 long minTimeForProvider = getMinTimeLocked(provider);
-                proxy.setMinTime(minTimeForProvider);
-                proxy.enableLocationTracking(true);
+                p.setMinTime(minTimeForProvider);
+                p.enableLocationTracking(true);
             } else {
                 // Notify the listener that updates are currently disabled
                 receiver.callProviderEnabledLocked(provider, false);
@@ -923,9 +921,9 @@
                 // Call dispose() on the obsolete update records.
                 for (UpdateRecord record : oldRecords.values()) {
                     if (!providerHasListener(record.mProvider, callingUid, receiver)) {
-                        LocationProviderProxy proxy = mProvidersByName.get(record.mProvider);
-                        if (proxy != null) {
-                            proxy.removeListener(callingUid);
+                        LocationProviderInterface p = mProvidersByName.get(record.mProvider);
+                        if (p != null) {
+                            p.removeListener(callingUid);
                         }
                     }
                     record.disposeLocked();
@@ -949,7 +947,7 @@
                     hasOtherListener = true;
                 }
 
-                LocationProviderProxy p = mProvidersByName.get(provider);
+                LocationProviderInterface p = mProvidersByName.get(provider);
                 if (p != null) {
                     if (hasOtherListener) {
                         p.setMinTime(getMinTimeLocked(provider));
@@ -1006,12 +1004,12 @@
         }
 
         synchronized (mLock) {
-            LocationProviderProxy proxy = mProvidersByName.get(provider);
-            if (proxy == null) {
+            LocationProviderInterface p = mProvidersByName.get(provider);
+            if (p == null) {
                 return false;
             }
     
-            return proxy.sendExtraCommand(command, extras);
+            return p.sendExtraCommand(command, extras);
         }
     }
 
@@ -1261,7 +1259,7 @@
             mProximityReceiver = new Receiver(mProximityListener);
 
             for (int i = mProviders.size() - 1; i >= 0; i--) {
-                LocationProviderProxy provider = mProviders.get(i);
+                LocationProviderInterface provider = mProviders.get(i);
                 requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver);
             }
         }
@@ -1311,7 +1309,7 @@
     }
 
     private Bundle _getProviderInfoLocked(String provider) {
-        LocationProviderProxy p = mProvidersByName.get(provider);
+        LocationProviderInterface p = mProvidersByName.get(provider);
         if (p == null || !p.isEnabled()) {
             return null;
         }
@@ -1359,7 +1357,7 @@
     private boolean _isProviderEnabledLocked(String provider) {
         checkPermissionsSafe(provider);
 
-        LocationProviderProxy p = mProvidersByName.get(provider);
+        LocationProviderInterface p = mProvidersByName.get(provider);
         if (p == null) {
             throw new IllegalArgumentException("provider=" + provider);
         }
@@ -1382,7 +1380,7 @@
     private Location _getLastKnownLocationLocked(String provider) {
         checkPermissionsSafe(provider);
 
-        LocationProviderProxy p = mProvidersByName.get(provider);
+        LocationProviderInterface p = mProvidersByName.get(provider);
         if (p == null) {
             throw new IllegalArgumentException("provider=" + provider);
         }
@@ -1424,7 +1422,7 @@
             return;
         }
 
-        LocationProviderProxy p = mProvidersByName.get(provider);
+        LocationProviderInterface p = mProvidersByName.get(provider);
         if (p == null) {
             return;
         }
@@ -1507,9 +1505,9 @@
 
                         // notify other providers of the new location
                         for (int i = mProviders.size() - 1; i >= 0; i--) {
-                            LocationProviderProxy proxy = mProviders.get(i);
-                            if (!provider.equals(proxy.getName())) {
-                                proxy.updateLocation(location);
+                            LocationProviderInterface p = mProviders.get(i);
+                            if (!provider.equals(p.getName())) {
+                                p.updateLocation(location);
                             }
                         }
 
@@ -1597,7 +1595,7 @@
                 // Notify location providers of current network state
                 synchronized (mLock) {
                     for (int i = mProviders.size() - 1; i >= 0; i--) {
-                        LocationProviderProxy provider = mProviders.get(i);
+                        LocationProviderInterface provider = mProviders.get(i);
                         if (provider.isEnabled() && provider.requiresNetwork()) {
                             provider.updateNetworkState(mNetworkState, info);
                         }
@@ -1698,16 +1696,16 @@
             // remove the real provider if we are replacing GPS or network provider
             if (LocationManager.GPS_PROVIDER.equals(name)
                     || LocationManager.NETWORK_PROVIDER.equals(name)) {
-                LocationProviderProxy proxy = mProvidersByName.get(name);
-                if (proxy != null) {
-                    proxy.enableLocationTracking(false);
-                    removeProvider(proxy);
+                LocationProviderInterface p = mProvidersByName.get(name);
+                if (p != null) {
+                    p.enableLocationTracking(false);
+                    removeProvider(p);
                 }
             }
             if (mProvidersByName.get(name) != null) {
                 throw new IllegalArgumentException("Provider \"" + name + "\" already exists");
             }
-            addProvider(new LocationProviderProxy(mContext, name, provider));
+            addProvider(provider);
             mMockProviders.put(name, provider);
             mLastKnownLocation.put(name, null);
             updateProvidersLocked();
diff --git a/test-runner/android/test/TestLocationProvider.java b/test-runner/android/test/TestLocationProvider.java
deleted file mode 100644
index dc07585..0000000
--- a/test-runner/android/test/TestLocationProvider.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.test;
-
-
-import android.location.Criteria;
-import android.location.ILocationManager;
-import android.location.ILocationProvider;
-import android.location.Location;
-import android.location.LocationProvider;
-import android.net.NetworkInfo;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.util.Log;
-
-/**
- * @hide - This is part of a framework that is under development and should not be used for
- * active development.
- */
-public class TestLocationProvider extends ILocationProvider.Stub {
-
-    public static final String PROVIDER_NAME = "test";
-    public static final double LAT = 0;
-    public static final double LON = 1;
-    public static final double ALTITUDE = 10000;
-    public static final float SPEED = 10;
-    public static final float BEARING = 1;
-    public static final int STATUS = LocationProvider.AVAILABLE;
-    private static final long LOCATION_INTERVAL = 1000;
-
-    private static final String TAG = "TestLocationProvider";
-
-    private final ILocationManager mLocationManager;
-    private Location mLocation;
-    private boolean mEnabled;
-    private TestLocationProviderThread mThread;
-
-    private class TestLocationProviderThread extends Thread {
-
-        private boolean mDone = false;
-
-        public TestLocationProviderThread() {
-            super("TestLocationProviderThread");
-        }
-
-        public void run() {            
-            // thread exits after disable() is called
-            synchronized (this) {
-                while (!mDone) {
-                    try {
-                        wait(LOCATION_INTERVAL);
-                    } catch (InterruptedException e) {
-                    }
-                    
-                    if (!mDone) {
-                        TestLocationProvider.this.updateLocation();
-                    }
-                }
-            }
-        }
-        
-        synchronized void setDone() {
-            mDone = true;
-            notify();
-        }
-    }
-
-    public TestLocationProvider(ILocationManager locationManager) {
-        mLocationManager = locationManager;
-        mLocation = new Location(PROVIDER_NAME);
-    }
-
-    public int getAccuracy() {
-        return Criteria.ACCURACY_COARSE;
-    }
-
-    public int getPowerRequirement() {
-        return Criteria.NO_REQUIREMENT;
-    }
-
-    public boolean hasMonetaryCost() {
-        return false;
-    }
-
-    public boolean requiresCell() {
-        return false;
-    }
-
-    public boolean requiresNetwork() {
-        return false;
-    }
-
-    public boolean requiresSatellite() {
-        return false;
-    }
-
-    public boolean supportsAltitude() {
-        return true;
-    }
-
-    public boolean supportsBearing() {
-        return true;
-    }
-
-    public boolean supportsSpeed() {
-        return true;
-    }
-
-    public synchronized void disable() {
-        mEnabled = false;
-        if (mThread != null) {
-            mThread.setDone();
-            try {
-                mThread.join();
-            } catch (InterruptedException e) {
-            }
-            mThread = null;
-        }
-    }
-
-    public synchronized void enable() {
-       mEnabled = true;
-        mThread = new TestLocationProviderThread();
-        mThread.start();
-    }
-
-    public boolean isEnabled() {
-        return mEnabled;
-    }
-
-    public int getStatus(Bundle extras) {
-        return STATUS;
-    }
-
-    public long getStatusUpdateTime() {
-        return 0;
-    }
-
-    public void enableLocationTracking(boolean enable) {
-    }
-
-    public void setMinTime(long minTime) {
-    }
-
-    public void updateNetworkState(int state, NetworkInfo info) {
-    }
-
-    public void updateLocation(Location location) {
-    }
-
-    public boolean sendExtraCommand(String command, Bundle extras) {
-        return false;
-    }
-
-    public void addListener(int uid) {
-    }
-
-    public void removeListener(int uid) {
-    }
-
-    private void updateLocation() {
-        long time = SystemClock.uptimeMillis();
-        long multiplier = (time/5000)%500000;
-        mLocation.setLatitude(LAT*multiplier);
-        mLocation.setLongitude(LON*multiplier);
-        mLocation.setAltitude(ALTITUDE);
-        mLocation.setSpeed(SPEED);
-        mLocation.setBearing(BEARING*multiplier);
-
-        Bundle extras = new Bundle();
-        extras.putInt("extraTest", 24);
-        mLocation.setExtras(extras);
-        mLocation.setTime(time);
-        try {
-            mLocationManager.reportLocation(mLocation);
-        } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException calling updateLocation");
-        }
-    }
-
-}