1/* 2 * Copyright (C) 2012 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 applicable 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.location.fused; 18 19 20import java.io.FileDescriptor; 21import java.io.PrintWriter; 22 23import com.android.location.provider.LocationProviderBase; 24import com.android.location.provider.ProviderPropertiesUnbundled; 25import com.android.location.provider.ProviderRequestUnbundled; 26 27import android.content.BroadcastReceiver; 28import android.content.Context; 29import android.content.Intent; 30import android.content.IntentFilter; 31import android.location.Criteria; 32import android.location.LocationProvider; 33import android.os.Bundle; 34import android.os.Handler; 35import android.os.Looper; 36import android.os.Message; 37import android.os.UserHandle; 38import android.os.WorkSource; 39 40public class FusedLocationProvider extends LocationProviderBase implements FusionEngine.Callback { 41 private static final String TAG = "FusedLocationProvider"; 42 43 private static ProviderPropertiesUnbundled PROPERTIES = ProviderPropertiesUnbundled.create( 44 false, false, false, false, true, true, true, Criteria.POWER_LOW, 45 Criteria.ACCURACY_FINE); 46 47 private static final int MSG_ENABLE = 1; 48 private static final int MSG_DISABLE = 2; 49 private static final int MSG_SET_REQUEST = 3; 50 51 private final Context mContext; 52 private final FusionEngine mEngine; 53 54 private static class RequestWrapper { 55 public ProviderRequestUnbundled request; 56 public WorkSource source; 57 public RequestWrapper(ProviderRequestUnbundled request, WorkSource source) { 58 this.request = request; 59 this.source = source; 60 } 61 } 62 63 public FusedLocationProvider(Context context) { 64 super(TAG, PROPERTIES); 65 mContext = context; 66 mEngine = new FusionEngine(context, Looper.myLooper()); 67 68 // listen for user change 69 IntentFilter intentFilter = new IntentFilter(); 70 intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 71 mContext.registerReceiverAsUser(new BroadcastReceiver() { 72 @Override 73 public void onReceive(Context context, Intent intent) { 74 String action = intent.getAction(); 75 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 76 mEngine.switchUser(); 77 } 78 } 79 }, UserHandle.ALL, intentFilter, null, mHandler); 80 } 81 82 /** 83 * For serializing requests to mEngine. 84 */ 85 private Handler mHandler = new Handler() { 86 @Override 87 public void handleMessage(Message msg) { 88 switch (msg.what) { 89 case MSG_ENABLE: 90 mEngine.init(FusedLocationProvider.this); 91 break; 92 case MSG_DISABLE: 93 mEngine.deinit(); 94 break; 95 case MSG_SET_REQUEST: 96 { 97 RequestWrapper wrapper = (RequestWrapper) msg.obj; 98 mEngine.setRequest(wrapper.request, wrapper.source); 99 break; 100 } 101 } 102 } 103 }; 104 105 @Override 106 public void onEnable() { 107 mHandler.sendEmptyMessage(MSG_ENABLE); 108 } 109 110 @Override 111 public void onDisable() { 112 mHandler.sendEmptyMessage(MSG_DISABLE); 113 } 114 115 @Override 116 public void onSetRequest(ProviderRequestUnbundled request, WorkSource source) { 117 mHandler.obtainMessage(MSG_SET_REQUEST, new RequestWrapper(request, source)).sendToTarget(); 118 } 119 120 @Override 121 public void onDump(FileDescriptor fd, PrintWriter pw, String[] args) { 122 // perform synchronously 123 mEngine.dump(fd, pw, args); 124 } 125 126 @Override 127 public int onGetStatus(Bundle extras) { 128 return LocationProvider.AVAILABLE; 129 } 130 131 @Override 132 public long onGetStatusUpdateTime() { 133 return 0; 134 } 135} 136