summaryrefslogtreecommitdiffstats
path: root/location/lib/java/com/android/location/provider/LocationProviderBase.java
blob: b0e5d2cfa2aa92f98363f0e81c8aed6febf45d10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
 * 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 java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintWriter;

import android.content.Context;
import android.location.ILocationManager;
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;

import com.android.internal.location.ILocationProvider;
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;

/**
 * Base class for location providers implemented as unbundled services.
 *
 * <p>The network location provider must export a service with action
 * "com.android.location.service.v2.NetworkLocationProvider"
 * and a valid minor version in a meta-data field on the service, and
 * then return the result of {@link #getBinder()} on service binding.
 *
 * <p>The fused location provider must export a service with action
 * "com.android.location.service.FusedLocationProvider"
 * and a valid minor version in a meta-data field on the service, and
 * then return the result of {@link #getBinder()} on service binding.
 *
 * <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.
 */
public abstract class LocationProviderBase {
    private final String TAG;

    protected final ILocationManager mLocationManager;
    private final ProviderProperties mProperties;
    private final IBinder mBinder;

    private final class Service extends ILocationProvider.Stub {
        @Override
        public void enable() {
            onEnable();
        }
        @Override
        public void disable() {
            onDisable();
        }
        @Override
        public void setRequest(ProviderRequest request, WorkSource ws) {
            onSetRequest(new ProviderRequestUnbundled(request), ws);
        }
        @Override
        public ProviderProperties getProperties() {
            return mProperties;
        }
        @Override
        public int getStatus(Bundle extras) {
            return onGetStatus(extras);
        }
        @Override
        public long getStatusUpdateTime() {
            return onGetStatusUpdateTime();
        }
        @Override
        public boolean sendExtraCommand(String command, Bundle extras) {
            return onSendExtraCommand(command, extras);
        }
        @Override
        public void dump(FileDescriptor fd, String[] args) {
            PrintWriter pw = new PrintWriter(new FileOutputStream(fd));
            onDump(fd, pw, args);
            pw.flush();
        }
    }

    public LocationProviderBase(String tag, ProviderPropertiesUnbundled properties) {
        TAG = tag;
        IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
        mLocationManager = ILocationManager.Stub.asInterface(b);
        mProperties = properties.getProviderProperties();
        mBinder = new Service();
    }

    public IBinder getBinder() {
        return mBinder;
    }

    /**
     * Used by the location provider to report new locations.
     *
     * @param location new Location to report
     *
     * Requires the android.permission.INSTALL_LOCATION_PROVIDER permission.
     */
    public final void reportLocation(Location location) {
        try {
            mLocationManager.reportLocation(location, false);
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException", e);
        } catch (Exception e) {
            // never crash provider, might be running in a system process
            Log.e(TAG, "Exception", e);
        }
    }

    /**
     * Enable the location provider.
     * <p>The provider may initialize resources, but does
     * not yet need to report locations.
     */
    public abstract void onEnable();

    /**
     * Disable the location provider.
     * <p>The provider must release resources, and stop
     * performing work. It may no longer report locations.
     */
    public abstract void onDisable();

    /**
     * Set the {@link ProviderRequest} requirements for this provider.
     * <p>Each call to this method overrides all previous requests.
     * <p>This method might trigger the provider to start returning
     * locations, or to stop returning locations, depending on the
     * parameters in the request.
     */
    public abstract void onSetRequest(ProviderRequestUnbundled request, WorkSource source);

    /**
     * Dump debug information.
     */
    public void onDump(FileDescriptor fd, PrintWriter pw, String[] args) {
    }

    /**
     * Returns a information on the status of this provider.
     * <p>{@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();

    /**
     * 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 boolean onSendExtraCommand(String command, Bundle extras) {
        // default implementation
        return false;
    }
}