OSDN Git Service

Reloads status messages for injected items
authorLifu Tang <lifu@google.com>
Fri, 23 Aug 2013 00:43:19 +0000 (17:43 -0700)
committerLifu Tang <lifu@google.com>
Fri, 23 Aug 2013 01:08:18 +0000 (18:08 -0700)
Change-Id: I6bb95c4b7ff4118074fb51aeed31596eab1e7eef

src/com/android/settings/location/LocationSettings.java
src/com/android/settings/location/SettingsInjector.java

index 4e54107..7d25144 100644 (file)
@@ -18,7 +18,11 @@ package com.android.settings.location;
 
 import android.app.ActionBar;
 import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.location.SettingInjectorService;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
@@ -53,8 +57,9 @@ public class LocationSettings extends LocationSettingsBase
     private Switch mSwitch;
     private boolean mValidListener;
     private Preference mLocationMode;
-
     private BatteryStatsHelper mStatsHelper;
+    /** Receives UPDATE_INTENT  */
+    private BroadcastReceiver mReceiver;
 
     public LocationSettings() {
         mValidListener = false;
@@ -89,6 +94,11 @@ public class LocationSettings extends LocationSettingsBase
 
     @Override
     public void onPause() {
+        try {
+            getActivity().unregisterReceiver(mReceiver);
+        } catch (RuntimeException e) {
+            // Ignore exceptions caused by race condition
+        }
         super.onPause();
         mValidListener = false;
         mSwitch.setOnCheckedChangeListener(null);
@@ -156,7 +166,18 @@ public class LocationSettings extends LocationSettingsBase
 
         PreferenceCategory categoryLocationServices =
                 (PreferenceCategory) root.findPreference(KEY_LOCATION_SERVICES);
-        List<Preference> locationServices = SettingsInjector.getInjectedSettings(activity);
+        final SettingsInjector injector = new SettingsInjector(activity);
+        List<Preference> locationServices = injector.getInjectedSettings();
+
+        mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                injector.reloadStatusMessages();
+            }
+        };
+        activity.registerReceiver(
+                mReceiver, new IntentFilter(SettingInjectorService.UPDATE_INTENT));
+
         if (locationServices.size() > 0) {
             addPreferencesSorted(locationServices, categoryLocationServices);
         } else {
index 41cd869..bdff37d 100644 (file)
@@ -79,6 +79,13 @@ class SettingsInjector {
      */
     public static final String ATTRIBUTES_NAME = "injected-location-setting";
 
+    private Context mContext;
+    private StatusLoader mLoader = null;
+
+    public SettingsInjector(Context context) {
+        mContext = context;
+    }
+
     /**
      * Returns a list with one {@link InjectedSetting} object for each {@link android.app.Service}
      * that responds to {@link #RECEIVER_INTENT} and provides the expected setting metadata.
@@ -87,8 +94,8 @@ class SettingsInjector {
      *
      * TODO: unit test
      */
-    public static List<InjectedSetting> getSettings(Context context) {
-        PackageManager pm = context.getPackageManager();
+    private List<InjectedSetting> getSettings() {
+        PackageManager pm = mContext.getPackageManager();
         Intent receiverIntent = new Intent(RECEIVER_INTENT);
 
         List<ResolveInfo> resolveInfos =
@@ -189,8 +196,7 @@ class SettingsInjector {
         }
     }
 
-    private static final class StatusLoader {
-        private final Context mContext;
+    private final class StatusLoader {
         private final Intent mIntent;
         private final StatusLoader mPrev;
 
@@ -199,13 +205,30 @@ class SettingsInjector {
         /**
          * Creates a loader and chains with the previous loader.
          */
-        public StatusLoader(Context context, Intent intent, StatusLoader prev) {
-            mContext = context;
+        public StatusLoader(Intent intent, StatusLoader prev) {
             mIntent = intent;
             mPrev = prev;
         }
 
         /**
+         * Clears the loaded flag for the whole chain.
+         */
+        private void setNotLoaded() {
+            mLoaded = false;
+            if (mPrev != null) {
+                mPrev.setNotLoaded();
+            }
+        }
+
+        /**
+         * Reloads the whole chain.
+         */
+        public void reload() {
+            setNotLoaded();
+            loadIfNotLoaded();
+        }
+
+        /**
          * If the current message hasn't been loaded, loads the status messages
          * and set time out for the next message.
          */
@@ -238,34 +261,41 @@ class SettingsInjector {
      * TODO: extract InjectedLocationSettingGetter that returns an iterable over
      * InjectedSetting objects, so that this class can focus on UI
      */
-    public static List<Preference> getInjectedSettings(Context context) {
-
-        Iterable<InjectedSetting> settings = getSettings(context);
+    public List<Preference> getInjectedSettings() {
+        Iterable<InjectedSetting> settings = getSettings();
         ArrayList<Preference> prefs = new ArrayList<Preference>();
-        StatusLoader loader = null;
+        mLoader = null;
         for (InjectedSetting setting : settings) {
-            Preference pref = addServiceSetting(context, prefs, setting);
-            Intent intent = createUpdatingIntent(context, pref, setting, loader);
-            loader = new StatusLoader(context, intent, loader);
+            Preference pref = addServiceSetting(prefs, setting);
+            Intent intent = createUpdatingIntent(pref, setting, mLoader);
+            mLoader = new StatusLoader(intent, mLoader);
         }
 
         // Start a thread to load each list item status.
-        if (loader != null) {
-            loader.loadIfNotLoaded();
+        if (mLoader != null) {
+            mLoader.loadIfNotLoaded();
         }
 
         return prefs;
     }
 
     /**
+     * Reloads the status messages for all the preference items.
+     */
+    public void reloadStatusMessages() {
+        if (mLoader != null) {
+            mLoader.reload();
+        }
+    }
+
+    /**
      * Adds an injected setting to the root with status "Loading...".
      */
-    private static Preference addServiceSetting(
-            Context context, List<Preference> prefs, InjectedSetting info) {
-        Preference pref = new Preference(context);
+    private Preference addServiceSetting(List<Preference> prefs, InjectedSetting info) {
+        Preference pref = new Preference(mContext);
         pref.setTitle(info.title);
         pref.setSummary(R.string.location_loading_injected_setting);
-        PackageManager pm = context.getPackageManager();
+        PackageManager pm = mContext.getPackageManager();
         Drawable icon = pm.getDrawable(info.packageName, info.iconId, null);
         pref.setIcon(icon);
 
@@ -281,7 +311,7 @@ class SettingsInjector {
      * Creates an Intent to ask the receiver for the current status for the setting, and display it
      * when it replies.
      */
-    private static Intent createUpdatingIntent(Context context,
+    private static Intent createUpdatingIntent(
             final Preference pref, final InjectedSetting info, final StatusLoader prev) {
         final Intent receiverIntent = info.getServiceIntent();
         Handler handler = new Handler() {