16fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly/*
26fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Copyright (C) 2012 The Android Open Source Project
36fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly *
46fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License");
56fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * you may not use this file except in compliance with the License.
66fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * You may obtain a copy of the License at
76fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly *
86fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly *      http://www.apache.org/licenses/LICENSE-2.0
96fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly *
106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Unless required by applicable law or agreed to in writing, software
116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS,
126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * See the License for the specific language governing permissions and
146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * limitations under the License.
156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */
166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellypackage com.android.location.fused;
186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport java.io.FileDescriptor;
216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport java.io.PrintWriter;
226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport com.android.location.provider.LocationProviderBase;
246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport com.android.location.provider.ProviderPropertiesUnbundled;
256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport com.android.location.provider.ProviderRequestUnbundled;
266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
2703cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Leaseimport android.content.BroadcastReceiver;
286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.content.Context;
2903cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Leaseimport android.content.Intent;
3003cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Leaseimport android.content.IntentFilter;
316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.location.Criteria;
326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.location.LocationProvider;
336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.os.Bundle;
346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.os.Handler;
356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.os.Looper;
366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.os.Message;
3703cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Leaseimport android.os.UserHandle;
386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.os.WorkSource;
396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellypublic class FusedLocationProvider extends LocationProviderBase implements FusionEngine.Callback {
416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    private static final String TAG = "FusedLocationProvider";
426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    private static ProviderPropertiesUnbundled PROPERTIES = ProviderPropertiesUnbundled.create(
446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly            false, false, false, false, true, true, true, Criteria.POWER_LOW,
456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly            Criteria.ACCURACY_FINE);
466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    private static final int MSG_ENABLE = 1;
486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    private static final int MSG_DISABLE = 2;
496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    private static final int MSG_SET_REQUEST = 3;
506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    private final Context mContext;
526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    private final FusionEngine mEngine;
536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    private static class RequestWrapper {
556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        public ProviderRequestUnbundled request;
566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        public WorkSource source;
576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        public RequestWrapper(ProviderRequestUnbundled request, WorkSource source) {
586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly            this.request = request;
596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly            this.source = source;
606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        }
616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    public FusedLocationProvider(Context context) {
646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        super(TAG, PROPERTIES);
656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        mContext = context;
666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        mEngine = new FusionEngine(context, Looper.myLooper());
6703cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease
6803cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease        // listen for user change
6903cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease        IntentFilter intentFilter = new IntentFilter();
7003cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease        intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
7103cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease        mContext.registerReceiverAsUser(new BroadcastReceiver() {
7203cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease            @Override
7303cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease            public void onReceive(Context context, Intent intent) {
7403cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease                String action = intent.getAction();
7503cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease                if (Intent.ACTION_USER_SWITCHED.equals(action)) {
7603cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease                    mEngine.switchUser();
7703cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease                }
7803cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease            }
7903cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease        }, UserHandle.ALL, intentFilter, null, mHandler);
806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    /**
836fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly     * For serializing requests to mEngine.
846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly     */
856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    private Handler mHandler = new Handler() {
866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        @Override
876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        public void handleMessage(Message msg) {
886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly            switch (msg.what) {
896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                case MSG_ENABLE:
906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                    mEngine.init(FusedLocationProvider.this);
916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                    break;
926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                case MSG_DISABLE:
936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                    mEngine.deinit();
946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                    break;
956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                case MSG_SET_REQUEST:
966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                    {
976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                        RequestWrapper wrapper = (RequestWrapper) msg.obj;
9808ca1046fe4f1890f91241f8d082a024ef6cfd93Nick Pelly                        mEngine.setRequest(wrapper.request, wrapper.source);
996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                        break;
1006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly                    }
1016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly            }
1026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        }
1036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    };
1046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
1056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    @Override
1066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    public void onEnable() {
1076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        mHandler.sendEmptyMessage(MSG_ENABLE);
1086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
1096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
1106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    @Override
1116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    public void onDisable() {
1126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        mHandler.sendEmptyMessage(MSG_DISABLE);
1136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
1146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
1156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    @Override
1166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    public void onSetRequest(ProviderRequestUnbundled request, WorkSource source) {
11708ca1046fe4f1890f91241f8d082a024ef6cfd93Nick Pelly        mHandler.obtainMessage(MSG_SET_REQUEST, new RequestWrapper(request, source)).sendToTarget();
1186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
1196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
1206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    @Override
1216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    public void onDump(FileDescriptor fd, PrintWriter pw, String[] args) {
1226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        // perform synchronously
1236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        mEngine.dump(fd, pw, args);
1246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
1256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
1266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    @Override
1276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    public int onGetStatus(Bundle extras) {
1286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        return LocationProvider.AVAILABLE;
1296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
1306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
1316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    @Override
1326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    public long onGetStatusUpdateTime() {
1336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        return 0;
1346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
1356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly}
136