1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (The "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.location;
18
19import com.android.server.ServiceWatcher;
20
21import android.Manifest;
22import android.content.Context;
23import android.hardware.location.IFusedLocationHardware;
24import android.location.IFusedProvider;
25import android.os.Handler;
26import android.os.RemoteException;
27import android.util.Log;
28
29/**
30 * Proxy that helps bind GCore FusedProvider implementations to the Fused Hardware instances.
31 *
32 * @hide
33 */
34public final class FusedProxy {
35    private final String TAG = "FusedProxy";
36    private final ServiceWatcher mServiceWatcher;
37    private final FusedLocationHardwareSecure mLocationHardware;
38
39    /**
40     * Constructor of the class.
41     * This is private as the class follows a factory pattern for construction.
42     *
43     * @param context           The context needed for construction.
44     * @param handler           The handler needed for construction.
45     * @param locationHardware  The instance of the Fused location hardware assigned to the proxy.
46     */
47    private FusedProxy(
48            Context context,
49            Handler handler,
50            IFusedLocationHardware locationHardware,
51            int overlaySwitchResId,
52            int defaultServicePackageNameResId,
53            int initialPackageNameResId) {
54        mLocationHardware = new FusedLocationHardwareSecure(
55                locationHardware,
56                context,
57                Manifest.permission.LOCATION_HARDWARE);
58        Runnable newServiceWork = new Runnable() {
59            @Override
60            public void run() {
61                bindProvider(mLocationHardware);
62            }
63        };
64
65        // prepare the connection to the provider
66        mServiceWatcher = new ServiceWatcher(
67                context,
68                TAG,
69                "com.android.location.service.FusedProvider",
70                overlaySwitchResId,
71                defaultServicePackageNameResId,
72                initialPackageNameResId,
73                newServiceWork,
74                handler);
75    }
76
77    /**
78     * Creates an instance of the proxy and binds it to the appropriate FusedProvider.
79     *
80     * @param context           The context needed for construction.
81     * @param handler           The handler needed for construction.
82     * @param locationHardware  The instance of the Fused location hardware assigned to the proxy.
83     *
84     * @return An instance of the proxy if it could be bound, null otherwise.
85     */
86    public static FusedProxy createAndBind(
87            Context context,
88            Handler handler,
89            IFusedLocationHardware locationHardware,
90            int overlaySwitchResId,
91            int defaultServicePackageNameResId,
92            int initialPackageNameResId) {
93        FusedProxy fusedProxy = new FusedProxy(
94                context,
95                handler,
96                locationHardware,
97                overlaySwitchResId,
98                defaultServicePackageNameResId,
99                initialPackageNameResId);
100
101        // try to bind the Fused provider
102        if (!fusedProxy.mServiceWatcher.start()) {
103            return null;
104        }
105
106        return fusedProxy;
107    }
108
109    /**
110     * Helper function to bind the FusedLocationHardware to the appropriate FusedProvider instance.
111     *
112     * @param locationHardware  The FusedLocationHardware instance to use for the binding operation.
113     */
114    private void bindProvider(IFusedLocationHardware locationHardware) {
115        IFusedProvider provider = IFusedProvider.Stub.asInterface(mServiceWatcher.getBinder());
116
117        if (provider == null) {
118            Log.e(TAG, "No instance of FusedProvider found on FusedLocationHardware connected.");
119            return;
120        }
121
122        try {
123            provider.onFusedLocationHardwareChange(locationHardware);
124        } catch (RemoteException e) {
125            Log.e(TAG, e.toString());
126        }
127    }
128}
129