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的方法

posted @ 2021-01-30 16:20  hlhuang  阅读(1470)  评论(0)    收藏  举报