目錄:
frameworks\base\services\core\java\com\android\server\location
GpsLocationProvider本身有一段初始化代碼,如下所示:
[java] view plain copy
- //GpsLP定義了一些native函數,此處的class_init_native将初始化相關JNI方法
- static { class_init_native(); }
下面看一下GpsLocationProvider的構造函數:
[java] view plain copy
- public GpsLocationProvider(Context context, ILocationManager ilocationManager,
- Looper looper) {
- mContext = context;
- mNtpTime = NtpTrustedTime.getInstance(context);
- mILocationManager = ilocationManager;
- mLocation.setExtras(mLocationExtras);
- // Create a wake lock
- mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
- mWakeLock.setReferenceCounted(true);
- mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
- mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
- mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
- mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
- // App ops service to keep track of who is accessing the GPS
- mAppOpsService = IAppOpsService.Stub.asInterface(ServiceManager.getService(
- Context.APP_OPS_SERVICE));
- // Battery statistics service to be notified when GPS turns on or off
- mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
- BatteryStats.SERVICE_NAME));
- // 加載GPS配置檔案,下文詳細介紹函數reloadGpsProperties
- mProperties = new Properties();
- reloadGpsProperties(mContext, mProperties);
- // 主要處理來自GPS HAL層通知的NI事件
- mNIHandler = new GpsNetInitiatedHandler(context,
- mNetInitiatedListener,
- mSuplEsEnabled);
- // construct handler, listen for events
- mHandler = new ProviderHandler(looper);
- //SUPL的初始化可以由兩種特殊的短信觸發,下文将簡單介紹listenForBroadcasts函數
- listenForBroadcasts();
- // 對PASSIVE_PROVIDER添加監聽
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- LocationManager locManager =
- (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
- final long minTime = 0;
- final float minDistance = 0;
- final boolean oneShot = false;
- LocationRequest request = LocationRequest.createFromDeprecatedProvider(
- LocationManager.PASSIVE_PROVIDER,
- minTime,
- minDistance,
- oneShot);
- request.setHideFromAppOps(true);
- //接收來自NetworkLP的位置更新通知
- //當GpsLP收到來自NetworkLP的位置資訊後,将把他們傳給GPS HAL層去處理
- locManager.requestLocationUpdates(
- request,
- new NetworkLocationListener(),
- mHandler.getLooper());
- }
- });
- }
函數reloadGpsProperties從檔案etc/gps.conf中加載了GPS相關參數包括SUPL伺服器位址、端口号等,代碼如下:
[java] view plain copy
- private void reloadGpsProperties(Context context, Properties properties) {
- Log.d(TAG, "Reset GPS properties, previous size = " + properties.size());
- loadPropertiesFromResource(context, properties);
- boolean isPropertiesLoadedFromFile = false;
- final String gpsHardware = SystemProperties.get("ro.hardware.gps");
- if (!TextUtils.isEmpty(gpsHardware)) {
- final String propFilename =
- PROPERTIES_FILE_PREFIX + "." + gpsHardware + PROPERTIES_FILE_SUFFIX;
- isPropertiesLoadedFromFile =
- loadPropertiesFromFile(propFilename, properties);
- }
- //加載檔案中的GPS屬性資訊
- if (!isPropertiesLoadedFromFile) {
- loadPropertiesFromFile(DEFAULT_PROPERTIES_FILE, properties);
- }
- Log.d(TAG, "GPS properties reloaded, size = " + properties.size());
- // 讀取配置檔案中的屬性資訊,通過JNI設定到HAL層
- setSuplHostPort(properties.getProperty("SUPL_HOST"),
- properties.getProperty("SUPL_PORT"));
- //C2K是CDMA2000的縮寫,C2K_HOST和C2K_PORT主要用于GPS子產品的測試,對使用者來說沒有太大意義
- mC2KServerHost = properties.getProperty("C2K_HOST");
- String portString = properties.getProperty("C2K_PORT");
- if (mC2KServerHost != null && portString != null) {
- try {
- mC2KServerPort = Integer.parseInt(portString);
- } catch (NumberFormatException e) {
- Log.e(TAG, "unable to parse C2K_PORT: " + portString);
- }
- }
- try {
- // Convert properties to string contents and send it to HAL.
- ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
- properties.store(baos, null);
- native_configuration_update(baos.toString());
- Log.d(TAG, "final config = " + baos.toString());
- } catch (IOException ex) {
- Log.w(TAG, "failed to dump properties contents");
- }
- // SUPL_ES configuration.
- String suplESProperty = mProperties.getProperty("SUPL_ES");
- if (suplESProperty != null) {
- try {
- mSuplEsEnabled = (Integer.parseInt(suplESProperty) == 1);
- } catch (NumberFormatException e) {
- Log.e(TAG, "unable to parse SUPL_ES: " + suplESProperty);
- }
- }
- }
下面我們來看一下listenForBroadcasts函數,其内容如下:
[java] view plain copy
- private void listenForBroadcasts() {
- IntentFilter intentFilter = new IntentFilter();
- //SUPL INIT流程可以由一條特殊的資料短信觸發。資料短信與文本短信不同,下面的這個IntentFilter将接收發往
- //127.0.0.1的資料短信。7275為OMA-SUPL使用的端口号
- intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
- intentFilter.addDataScheme("sms");
- intentFilter.addDataAuthority("localhost","7275");
- mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
- //SUPL INIT也可由WAP推送短信觸發,該短信包含的資料類型為MIME中的"application/vnd.omaloc-supl-init"
- 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, mHandler);
- //監聽ALARM事件、網絡事件等
- intentFilter = new IntentFilter();
- intentFilter.addAction(ALARM_WAKEUP);
- intentFilter.addAction(ALARM_TIMEOUT);
- intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
- intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
- intentFilter.addAction(Intent.ACTION_SCREEN_ON);
- intentFilter.addAction(SIM_STATE_CHANGED);
- // TODO: remove the use TelephonyIntents. We are using it because SIM_STATE_CHANGED
- // is not reliable at the moment.
- intentFilter.addAction(TelephonyIntents.ACTION_SUBINFO_CONTENT_CHANGE);
- intentFilter.addAction(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED);
- mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
- }
當GpsLP收到指定的資料短信或WAP推送短信後,checkSmsSuplInit或checkWapSuplInit函數将被調用。這兩個函數的功能比較簡單,就是将短信的内容傳遞到GPS HAL層,下面是它們的代碼:
[java] view plain copy
- private void checkSmsSuplInit(Intent intent) {
- SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
- for (int i=0; i <messages.length; i++) {
- byte[] supl_init = messages[i].getUserData();
- native_agps_ni_message(supl_init,supl_init.length);
- }
- }
- private void checkWapSuplInit(Intent intent) {
- byte[] supl_init = (byte[]) intent.getExtra("data");
- native_agps_ni_message(supl_init,supl_init.length);
- }
GpsLP初始化完畢。
參考文獻:《深入了解Android:WiFi、NFC和GPS卷》
原文:http://blog.csdn.net/dreamback1987/article/details/46789903