Android LocationManagerService启动(二)
接着上一篇文章
Android LocationManagerService启动(一)
LocationManagerService后就进入到了具体的Provider初始化部分,重点看GnssLocationProvider
GnssLocationProvider
LocationManagerService作为LocationProvider的管理服务,管理着多种不通的Provider,有些Provider是通过Proxy代理绑定的,这些Provider一般由第三方厂商去实现,对于系统而言,最重要,最基础的就是GnssProvider。GnssProvider管理着各种GPS Sensor的初始化,启用,关闭等各种操作。
构造函数
构造函数有三个参数,其中
- Context是LocationManagerService中的mContext
- ILocationManager就是LocationManagerService自身实例,他的作用就是用来回掉LocationManagerService的reportLocation和reportLocationBatch两个方法
- Looper是LocationManagerService里面mLocationHandler的looper,会根据这个传入的looper,创建一个内部的ProviderHandler,用来处理内部的消息。Provider内部的任何IO操作都会给到Handler来处理
public GnssLocationProvider(Context context, ILocationManager ilocationManager, Looper looper){
mContext = context;
mILocationManager = ilocationManager;
// Create a wake lock
mPowerManager = (PowerManager) mContextgetSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLoc(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
mWakeLock.setReferenceCounted(true);
// Create a separate wake lock for xtradownloader as it may be released due totimeout.
mDownloadXtraWakeLock = mPowerManagernewWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
mDownloadXtraWakeLock.setReferenceCounted(true;
mAlarmManager = (AlarmManager) mContextgetSystemService(Context.ALARM_SERVICE);
mWakeupIntent = PendingIntent.getBroadcas(mContext, 0, new Intent(ALARM_WAKEUP), 0);
mTimeoutIntent = PendingIntent.getBroadcas(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
mConnMgr = (ConnectivityManager) contextgetSystemService(Context.CONNECTIVITY_SERVICE);
// App ops service to keep track of who isaccessing the GPS
mAppOps = mContext.getSystemServic(AppOpsManager.class);
// Battery statistics service to be notifiedwhen GPS turns on or off
mBatteryStats = IBatteryStats.Stub.asInterfac(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
// Construct internal handler
mHandler = new ProviderHandler(looper);
// Load GPS configuration and registerlisteners in the background:
// some operations, such as opening files andregistering broadcast receivers, can take a
// relative long time, so the ctor() is keptto create objects needed by this instance,
// while IO initialization and registration isdelegated to our internal handler
// this approach is just fine because eventsare posted to our handler anyway
mProperties = new Properties();
sendMessage(INITIALIZE_HANDLER, 0, null);
// Create a GPS net-initiated handler.
mNIHandler = new GpsNetInitiatedHandle(context,
mNetInitiatedListener,
mSuplEsEnabled);
mListenerHelper = new GnssStatusListenerHelpe(mHandler) {
@Override
protected boolean isAvailableInPlatform() {
return isSupported();
}
@Override
protected boolean isGpsEnabled() {
return isEnabled();
}
};
mGnssMeasurementsProvider = newGnssMeasurementsProvider(mContext, mHandler) {
@Override
protected boolean isGpsEnabled() {
return isEnabled();
}
};
mGnssNavigationMessageProvider = newGnssNavigationMessageProvider(mHandler) {
@Override
protected boolean isGpsEnabled() {
return isEnabled();
}
};
mGnssMetrics = new GnssMetrics(mBatteryStats);
mNtpTimeHelper = new NtpTimeHelper(mContext,looper, this);
mGnssSatelliteBlacklistHelper = newGnssSatelliteBlacklistHelper(mContext,
looper, this);
mHandler.pos(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
mGnssBatchingProvider = new GnssBatchingProvider();
mGnssGeofenceProvider = new GnssGeofenceProvider(looper);
}
enable() and disable()
-
开启provider
开启Provider,需要处理getStatus方法,这个方法可能会开启硬件,导致状态变化 -
关闭provider
关闭Provider,也需要处理getStatus方法,也可能导致硬件变化 -
从这两个函数可以看出,最后的操作都通过sendMessage给出,交给Handler处理
@Override
public void enable() {
synchronized (mLock) {
if (mEnabled) return;
mEnabled = true;
}
sendMessage(ENABLE, 1, null);
}
@Override
public void disable() {
synchronized (mLock) {
if (!mEnabled) return;
mEnabled = false;
}
sendMessage(ENABLE, 0, null);
}
private void sendMessage(int message, int arg,Object obj) {
// hold a wake lock until this message is delivered
// note that this assumes the message will not be removed from the queue before
// it is handled (otherwise the wake lock would be leaked).
mWakeLock.acquire();
if (Log.isLoggable(TAG, Log.INFO)) {
Log.i(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
+ ", " + obj + ")");
}
mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
}
Provider
GNSS Provider 对外的方法最后都会给到Handle来处理。
private final class ProviderHandler extendsHandler {
public ProviderHandler(Looper looper) {
super(looper, null, true /*async*/);
}
@Override
public void handleMessage(Message msg) {
int message = msg.what;
switch (message) {
case ENABLE:
if (msg.arg1 == 1) {
handleEnable();
} else {
handleDisable();
}
break;
case SET_REQUEST:
GpsRequest gpsRequest = (GpsRequest) msg.obj;
handleSetRequest(gpsRequest.request, gpsRequest.source);
break;
case UPDATE_NETWORK_STATE:
handleUpdateNetworkState((Network) msg.obj);
break;
case REQUEST_SUPL_CONNECTION:
handleRequestSuplConnection((InetAddress) msg.obj);
break;
case RELEASE_SUPL_CONNECTION:
handleReleaseSuplConnection(msg.arg1);
break;
case INJECT_NTP_TIME:
mNtpTimeHelper.retrieveAndInjectNtpTime();
break;
case REQUEST_LOCATION:
handleRequestLocation((boolean) msg.obj);
break;
case DOWNLOAD_XTRA_DATA:
handleDownloadXtraData();
break;
case DOWNLOAD_XTRA_DATA_FINISHED:
mDownloadXtraDataPending = STATE_IDLE;
break;
case UPDATE_LOCATION:
handleUpdateLocation((Location) msg.obj);
break;
case SUBSCRIPTION_OR_SIM_CHANGED:
subscriptionOrSimChanged(mContext);
break;
case INITIALIZE_HANDLER:
handleInitialize();
break;
case REPORT_LOCATION:
handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
break;
case REPORT_SV_STATUS:
handleReportSvStatus((SvStatusInfo) msg.obj);
break;
}
if (msg.arg2 == 1) {
// wakelock was taken for this message, release it
mWakeLock.release();
if (Log.isLoggable(TAG, Log.INFO)) {
Log.i(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
+ ", " + msg.arg1 + ", " + msg.obj + ")");
}
}
}
/**
* This method is bound to {@link #GnssLocationProvider(Context, ILocationManager, Looper)}.
* It is in charge of loading properties and registering for events that will be posted to
* this handler.
*/
private void handleInitialize() {
native_init_once();
/*
* A cycle of native_init() and native_cleanup() is needed so that callbacks are
* registered after bootup even when location is disabled.
* This will allow Emergency SUPL to work even when location is disabled before device
* restart.
*/
boolean isInitialized = native_init();
if (!isInitialized) {
Log.w(TAG, "Native initialization failed at bootup");
} else {
native_cleanup();
}
// load default GPS configuration
// (this configuration might change in the future based on SIM changes)
reloadGpsProperties(mContext, mProperties);
// TODO: When this object "finishes" we should unregister by invoking
// SubscriptionManager.getInstance(mContext).unregister
// (mOnSubscriptionsChangedListener);
// This is not strictly necessary because it will be unregistered if the
// notification fails but it is good form.
// Register for SubscriptionInfo list changes which is guaranteed
// to invoke onSubscriptionsChanged the first time.
SubscriptionManager.from(mContext)
.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
// listen for events
IntentFilter intentFilter;
if (native_is_agps_ril_supported()) {
intentFilter = new IntentFilter();
intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
intentFilter.addDataScheme("sms");
intentFilter.addDataAuthority("localhost", "7275");
mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
intentFilter = new IntentFilter();
intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
try {
intentFilter.addDataType("application/vnd.omaloc-supl-init");
} catch (IntentFilter.MalformedMimeTypeException e) {
Log.w(TAG, "Malformed SUPL init mime type");
}
mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
} else if (DEBUG) {
Log.d(TAG, "Skipped registration for SMS/WAP-PUSH messages because AGPS Ril in GPS"
+ " HAL is not supported");
}
intentFilter = new IntentFilter();
intentFilter.addAction(ALARM_WAKEUP);
intentFilter.addAction(ALARM_TIMEOUT);
intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(SIM_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
// register for connectivity change events, this is equivalent to the deprecated way of
// registering for CONNECTIVITY_ACTION broadcasts
NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
networkRequestBuilder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
NetworkRequest networkRequest = networkRequestBuilder.build();
mConnMgr.registerNetworkCallback(networkRequest, mNetworkConnectivityCallback);
// listen for PASSIVE_PROVIDER updates
LocationManager locManager =
(LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
long minTime = 0;
float minDistance = 0;
boolean oneShot = false;
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
LocationManager.PASSIVE_PROVIDER,
minTime,
minDistance,
oneShot);
// Don't keep track of this request since it's done on behalf of other clients
// (which are kept track of separately).
request.setHideFromAppOps(true);
locManager.requestLocationUpdates(
request,
new NetworkLocationListener(),
getLooper());
}
}
从这里可以看出,所有的操作都给到了ProviderHandle来处理,对应的方法就是handlexxx的方法

浙公网安备 33010602011771号