summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordestradaa <destradaa@google.com>2015-04-16 14:01:27 -0700
committerdestradaa <destradaa@google.com>2015-04-16 14:05:30 -0700
commitfb23c67e8a0083ee376ad3f0e98f97d06755eb57 (patch)
tree988585fc473c8fcf1b15c2518b5b44ee830f6e29
parent5c86e922dd3473c0cf235ac9288d68099c293e53 (diff)
downloadframeworks_base-fb23c67e8a0083ee376ad3f0e98f97d06755eb57.zip
frameworks_base-fb23c67e8a0083ee376ad3f0e98f97d06755eb57.tar.gz
frameworks_base-fb23c67e8a0083ee376ad3f0e98f97d06755eb57.tar.bz2
Update GpsLocationProvider construction sequence to save time on startup.
b/20127262 This change moves long running operations: such as IO and broadcast receivers registration to its internal handler. This sets the time to execute GpsLocationProvider ctor() to ~14ms. A significant improvement from the 285ms reported originally in the bug. Change-Id: I4ee4183a1afea86117004c0a052957b8bc1e4ce5
-rw-r--r--services/core/java/com/android/server/location/GpsLocationProvider.java160
1 files changed, 90 insertions, 70 deletions
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 7c41abb..a279e0f 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -197,6 +197,8 @@ public class GpsLocationProvider implements LocationProviderInterface {
private static final int REMOVE_LISTENER = 9;
private static final int INJECT_NTP_TIME_FINISHED = 10;
private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
+ private static final int SUBSCRIPTION_OR_SIM_CHANGED = 12;
+ private static final int INITIALIZE_HANDLER = 13;
// Request setid
private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
@@ -338,8 +340,12 @@ public class GpsLocationProvider implements LocationProviderInterface {
// True if gps should be disabled (used to support battery saver mode in settings).
private boolean mDisableGps = false;
- // properties loaded from PROPERTIES_FILE
+ /**
+ * Properties loaded from PROPERTIES_FILE.
+ * It must be accessed only inside {@link #mHandler}.
+ */
private Properties mProperties;
+
private String mSuplServerHost;
private int mSuplServerPort = TCP_MIN_PORT;
private String mC2KServerHost;
@@ -462,7 +468,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
new OnSubscriptionsChangedListener() {
@Override
public void onSubscriptionsChanged() {
- subscriptionOrSimChanged(mContext);
+ sendMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null);
}
};
@@ -627,53 +633,22 @@ public class GpsLocationProvider implements LocationProviderInterface {
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
- // Load GPS configuration.
+ // Construct internal handler
+ mHandler = new ProviderHandler(looper);
+
+ // Load GPS configuration and register listeners in the background:
+ // some operations, such as opening files and registering broadcast receivers, can take a
+ // relative long time, so the ctor() is kept to create objects needed by this instance,
+ // while IO initialization and registration is delegated to our internal handler
+ // this approach is just fine because events are posted to our handler anyway
mProperties = new Properties();
- reloadGpsProperties(mContext, mProperties);
+ sendMessage(INITIALIZE_HANDLER, 0, null);
// Create a GPS net-initiated handler.
mNIHandler = new GpsNetInitiatedHandler(context,
mNetInitiatedListener,
mSuplEsEnabled);
- // 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);
-
- // construct handler, listen for events
- mHandler = new ProviderHandler(looper);
- listenForBroadcasts();
-
- // also listen for PASSIVE_PROVIDER updates
- 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);
- // 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(),
- mHandler.getLooper());
- }
- });
-
mListenerHelper = new GpsStatusListenerHelper(mHandler) {
@Override
protected boolean isAvailableInPlatform() {
@@ -731,33 +706,6 @@ public class GpsLocationProvider implements LocationProviderInterface {
};
}
- private void listenForBroadcasts() {
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
- intentFilter.addDataScheme("sms");
- intentFilter.addDataAuthority("localhost","7275");
- mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
-
- 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);
-
- intentFilter = new IntentFilter();
- intentFilter.addAction(ALARM_WAKEUP);
- intentFilter.addAction(ALARM_TIMEOUT);
- intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
- 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);
- mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
- }
-
/**
* Returns the name of this provider.
*/
@@ -2012,13 +1960,85 @@ public class GpsLocationProvider implements LocationProviderInterface {
case UPDATE_LOCATION:
handleUpdateLocation((Location)msg.obj);
break;
+ case SUBSCRIPTION_OR_SIM_CHANGED:
+ subscriptionOrSimChanged(mContext);
+ break;
+ case INITIALIZE_HANDLER:
+ initialize();
+ break;
}
if (msg.arg2 == 1) {
// wakelock was taken for this message, release it
mWakeLock.release();
}
}
- };
+
+ /**
+ * This method is bound to {@link #GpsLocationProvider(Context, ILocationManager, Looper)}.
+ * It is in charge of loading properties and registering for events that will be posted to
+ * this handler.
+ */
+ private void initialize() {
+ // 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 = 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);
+
+ intentFilter = new IntentFilter();
+ intentFilter.addAction(ALARM_WAKEUP);
+ intentFilter.addAction(ALARM_TIMEOUT);
+ intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
+ 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);
+ mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
+
+ // 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());
+ }
+ }
private final class NetworkLocationListener implements LocationListener {
@Override