OSDN Git Service

Make Print Settings use the new PrintManager.getPrintServices loader
authorPhilip P. Moltmann <moltmann@google.com>
Wed, 24 Feb 2016 20:11:05 +0000 (12:11 -0800)
committerPhilip P. Moltmann <moltmann@google.com>
Mon, 7 Mar 2016 17:32:55 +0000 (09:32 -0800)
This makes sure that all data always stays up to date.

printer_dropdown_item.xml:
- Reduce the amount of overriden properties

PrintServiceSettingsFragment:
- Instead receiving most data from PrintSettingsFragment have own loader
  and keep data up to date
- Also the updating of the print service state now has a dedicated
  PrintManager call instead of relying of the Settings-ContentObserver
  to transport this information. No more race-conditions, whohoo!

DynamicIndexableContentMonitor:
- To not rewrite too much code the update logic has to live here but the
  reading of the actual data is in PrintSettingsFragment.

Change-Id: I60715cda8952565d7f68cb24fb7da61a37085887

res/layout/printer_dropdown_item.xml
src/com/android/settings/SettingsActivity.java
src/com/android/settings/print/PrintServiceSettingsFragment.java
src/com/android/settings/print/PrintSettingsFragment.java
src/com/android/settings/print/PrintSettingsUtils.java [deleted file]
src/com/android/settings/search/DynamicIndexableContentMonitor.java

index 1e3f1a8..1036e24 100644 (file)
@@ -28,8 +28,6 @@
         android:layout_width="40dip"
         android:layout_height="40dip"
         android:layout_gravity="center_vertical"
-        android:layout_marginTop="8dip"
-        android:layout_marginBottom="8dip"
         android:duplicateParentState="true"
         android:contentDescription="@null"
         android:visibility="invisible">
             android:id="@+id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textAppearance="?android:attr/textAppearanceListItem"
             android:singleLine="true"
             android:ellipsize="end"
-            android:textIsSelectable="false"
-            android:layout_alignParentTop="true"
-            android:layout_alignParentStart="true"
-            android:fadingEdge="horizontal"
-            android:textAlignment="viewStart"
-            android:textColor="?android:attr/textColorPrimary"
-            android:duplicateParentState="true">
-        </TextView>
+            android:duplicateParentState="true" />
 
         <TextView
             android:id="@+id/subtitle"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_below="@id/title"
-            android:layout_alignParentStart="true"
-            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+            android:textColor="?android:attr/textColorSecondary"
             android:singleLine="true"
             android:ellipsize="end"
-            android:textIsSelectable="false"
             android:visibility="gone"
-            android:textColor="?android:attr/textColorSecondary"
-            android:textAlignment="viewStart"
-            android:duplicateParentState="true">
-        </TextView>
+            android:duplicateParentState="true" />
 
     </RelativeLayout>
 
-    <ImageView
+    <!-- wrapper for image view to increase the touch target size -->
+    <LinearLayout
         android:id="@+id/more_info"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:paddingLeft="16dip"
-        android:contentDescription="@string/printer_info_desc"
-        android:src="@drawable/ic_info_outline"
-        android:tint="?android:attr/colorControlNormal"
-        android:tintMode="src_in"
+        android:layout_height="fill_parent"
         android:visibility="gone">
-    </ImageView>
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:paddingLeft="16dip"
+            android:contentDescription="@string/printer_info_desc"
+            android:src="@drawable/ic_info"
+            android:tint="?android:attr/colorControlNormal"
+            android:tintMode="src_in" />
+
+    </LinearLayout>
 
 </LinearLayout>
index 8dafd74..2bce5b6 100644 (file)
@@ -131,6 +131,8 @@ public class SettingsActivity extends SettingsDrawerActivity
 
     private static final String LOG_TAG = "Settings";
 
+    private static final int LOADER_ID_INDEXABLE_CONTENT_MONITOR = 1;
+
     // Constants for state save/restore
     private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
     private static final String SAVE_KEY_SEARCH_MENU_EXPANDED = ":settings:search_menu_expanded";
@@ -786,7 +788,7 @@ public class SettingsActivity extends SettingsDrawerActivity
         registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_ADDED));
         registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED));
 
-        mDynamicIndexableContentMonitor.register(this);
+        mDynamicIndexableContentMonitor.register(this, LOADER_ID_INDEXABLE_CONTENT_MONITOR);
 
         if(mDisplaySearch && !TextUtils.isEmpty(mSearchQuery)) {
             onQueryTextSubmit(mSearchQuery);
index a9dba1e..6d6967b 100644 (file)
@@ -19,25 +19,23 @@ package com.android.settings.print;
 import android.app.Activity;
 import android.app.LoaderManager;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender.SendIntentException;
 import android.content.Loader;
 import android.content.pm.ResolveInfo;
-import android.database.ContentObserver;
 import android.database.DataSetObserver;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.net.Uri;
 import android.os.Bundle;
-import android.os.Handler;
 import android.print.PrintManager;
+import android.print.PrintServicesLoader;
 import android.print.PrinterDiscoverySession;
 import android.print.PrinterDiscoverySession.OnPrintersChangeListener;
 import android.print.PrinterId;
 import android.print.PrinterInfo;
+import android.printservice.PrintServiceInfo;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.TypedValue;
@@ -53,6 +51,7 @@ import android.widget.BaseAdapter;
 import android.widget.Filter;
 import android.widget.Filterable;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.SearchView;
 import android.widget.Switch;
@@ -74,19 +73,13 @@ import java.util.Map;
  * Fragment with print service settings.
  */
 public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
-        implements SwitchBar.OnSwitchChangeListener {
+        implements SwitchBar.OnSwitchChangeListener,
+        LoaderManager.LoaderCallbacks<List<PrintServiceInfo>> {
 
     private static final String LOG_TAG = "PrintServiceSettingsFragment";
 
     private static final int LOADER_ID_PRINTERS_LOADER = 1;
-
-    private final SettingsContentObserver mSettingsContentObserver =
-            new SettingsContentObserver(new Handler()) {
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            updateUiForServiceState();
-        }
-    };
+    private static final int LOADER_ID_PRINT_SERVICE_LOADER = 2;
 
     private final DataSetObserver mDataObserver = new DataSetObserver() {
         @Override
@@ -115,10 +108,8 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
 
     private String mPreferenceKey;
 
-    private CharSequence mSettingsTitle;
     private Intent mSettingsIntent;
 
-    private CharSequence mAddPrintersTitle;
     private Intent mAddPrintersIntent;
 
     private ComponentName mComponentName;
@@ -144,6 +135,8 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
+        mServiceEnabled = getArguments().getBoolean(PrintSettingsFragment.EXTRA_CHECKED);
+
         String title = getArguments().getString(PrintSettingsFragment.EXTRA_TITLE);
         if (!TextUtils.isEmpty(title)) {
             getActivity().setTitle(title);
@@ -153,8 +146,6 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
     @Override
     public void onStart() {
         super.onStart();
-        mSettingsContentObserver.register(getContentResolver());
-
         updateEmptyView();
         updateUiForServiceState();
     }
@@ -169,7 +160,6 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
 
     @Override
     public void onStop() {
-        mSettingsContentObserver.unregister(getContentResolver());
         super.onStop();
     }
 
@@ -192,14 +182,8 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
     }
 
     private void onPreferenceToggled(String preferenceKey, boolean enabled) {
-        ComponentName service = ComponentName.unflattenFromString(preferenceKey);
-        List<ComponentName> services = PrintSettingsUtils.readDisabledPrintServices(getActivity());
-        if (enabled) {
-            services.remove(service);
-        } else {
-            services.add(service);
-        }
-        PrintSettingsUtils.writeDisabledPrintServices(getActivity(), services);
+        ((PrintManager)getContext().getSystemService(Context.PRINT_SERVICE))
+                .setPrintServiceEnabled(mComponentName, enabled);
     }
 
     private ListView getBackupListView() {
@@ -255,9 +239,6 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
     }
 
     private void updateUiForServiceState() {
-        List<ComponentName> disabledServices = PrintSettingsUtils
-                .readDisabledPrintServices(getActivity());
-        mServiceEnabled = !disabledServices.contains(mComponentName);
         if (mServiceEnabled) {
             mSwitchBar.setCheckedInternal(true);
             mPrintersAdapter.enable();
@@ -315,56 +296,87 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
     private void updateUiForArguments() {
         Bundle arguments = getArguments();
 
+        // Component name.
+        mComponentName = ComponentName.unflattenFromString(arguments
+                .getString(PrintSettingsFragment.EXTRA_SERVICE_COMPONENT_NAME));
+
         // Key.
-        mPreferenceKey = arguments.getString(PrintSettingsFragment.EXTRA_PREFERENCE_KEY);
+        mPreferenceKey = mComponentName.flattenToString();
 
         // Enabled.
         final boolean enabled = arguments.getBoolean(PrintSettingsFragment.EXTRA_CHECKED);
         mSwitchBar.setCheckedInternal(enabled);
 
-        // Settings title and intent.
-        String settingsTitle = arguments.getString(PrintSettingsFragment.EXTRA_SETTINGS_TITLE);
-        String settingsComponentName = arguments.getString(
-                PrintSettingsFragment.EXTRA_SETTINGS_COMPONENT_NAME);
-        if (!TextUtils.isEmpty(settingsTitle) && !TextUtils.isEmpty(settingsComponentName)) {
+        getLoaderManager().initLoader(LOADER_ID_PRINT_SERVICE_LOADER, null, this);
+        setHasOptionsMenu(true);
+    }
+
+    @Override
+    public Loader<List<PrintServiceInfo>> onCreateLoader(int id, Bundle args) {
+        return new PrintServicesLoader(
+                (PrintManager) getContext().getSystemService(Context.PRINT_SERVICE), getContext(),
+                PrintManager.ALL_SERVICES);
+    }
+
+    @Override
+    public void onLoadFinished(Loader<List<PrintServiceInfo>> loader,
+            List<PrintServiceInfo> services) {
+        PrintServiceInfo service = null;
+
+        if (services != null) {
+            final int numServices = services.size();
+            for (int i = 0; i < numServices; i++) {
+                if (services.get(i).getComponentName().equals(mComponentName)) {
+                    service = services.get(i);
+                    break;
+                }
+            }
+        }
+
+        if (service == null) {
+            // The print service was uninstalled
+            finishFragment();
+        }
+
+        mServiceEnabled = service.isEnabled();
+
+        if (service.getSettingsActivityName() != null) {
             Intent settingsIntent = new Intent(Intent.ACTION_MAIN).setComponent(
-                    ComponentName.unflattenFromString(settingsComponentName.toString()));
+                    ComponentName.unflattenFromString(service.getSettingsActivityName()));
             List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities(
                     settingsIntent, 0);
             if (!resolvedActivities.isEmpty()) {
                 // The activity is a component name, therefore it is one or none.
                 if (resolvedActivities.get(0).activityInfo.exported) {
-                    mSettingsTitle = settingsTitle;
                     mSettingsIntent = settingsIntent;
                 }
             }
+        } else {
+            mSettingsIntent = null;
         }
 
-        // Add printers title and intent.
-        String addPrintersTitle = arguments.getString(
-                PrintSettingsFragment.EXTRA_ADD_PRINTERS_TITLE);
-        String addPrintersComponentName =
-                arguments.getString(PrintSettingsFragment.EXTRA_ADD_PRINTERS_COMPONENT_NAME);
-        if (!TextUtils.isEmpty(addPrintersTitle)
-                && !TextUtils.isEmpty(addPrintersComponentName)) {
-            Intent addPritnersIntent = new Intent(Intent.ACTION_MAIN).setComponent(
-                    ComponentName.unflattenFromString(addPrintersComponentName.toString()));
+        if (service.getAddPrintersActivityName() != null) {
+            Intent addPrintersIntent = new Intent(Intent.ACTION_MAIN)
+                    .setComponent(ComponentName.unflattenFromString(
+                            service.getAddPrintersActivityName()));
             List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities(
-                    addPritnersIntent, 0);
+                    addPrintersIntent, 0);
             if (!resolvedActivities.isEmpty()) {
                 // The activity is a component name, therefore it is one or none.
                 if (resolvedActivities.get(0).activityInfo.exported) {
-                    mAddPrintersTitle = addPrintersTitle;
-                    mAddPrintersIntent = addPritnersIntent;
+                    mAddPrintersIntent = addPrintersIntent;
                 }
             }
+        } else {
+            mAddPrintersIntent = null;
         }
 
-        // Component name.
-        mComponentName = ComponentName.unflattenFromString(arguments
-                .getString(PrintSettingsFragment.EXTRA_SERVICE_COMPONENT_NAME));
+        updateUiForServiceState();
+    }
 
-        setHasOptionsMenu(true);
+    @Override
+    public void onLoaderReset(Loader<List<PrintServiceInfo>> loader) {
+        updateUiForServiceState();
     }
 
     @Override
@@ -373,16 +385,14 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
         inflater.inflate(R.menu.print_service_settings, menu);
 
         MenuItem addPrinters = menu.findItem(R.id.print_menu_item_add_printer);
-        if (mServiceEnabled && !TextUtils.isEmpty(mAddPrintersTitle)
-                && mAddPrintersIntent != null) {
+        if (mServiceEnabled && mAddPrintersIntent != null) {
             addPrinters.setIntent(mAddPrintersIntent);
         } else {
             menu.removeItem(R.id.print_menu_item_add_printer);
         }
 
         MenuItem settings = menu.findItem(R.id.print_menu_item_settings);
-        if (mServiceEnabled && !TextUtils.isEmpty(mSettingsTitle)
-                && mSettingsIntent != null) {
+        if (mServiceEnabled && mSettingsIntent != null) {
             settings.setIntent(mSettingsIntent);
         } else {
             menu.removeItem(R.id.print_menu_item_settings);
@@ -426,25 +436,6 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
         }
     }
 
-    private static abstract class SettingsContentObserver extends ContentObserver {
-
-        public SettingsContentObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void register(ContentResolver contentResolver) {
-            contentResolver.registerContentObserver(android.provider.Settings.Secure.getUriFor(
-                    android.provider.Settings.Secure.DISABLED_PRINT_SERVICES), false, this);
-        }
-
-        public void unregister(ContentResolver contentResolver) {
-            contentResolver.unregisterContentObserver(this);
-        }
-
-        @Override
-        public abstract void onChange(boolean selfChange, Uri uri);
-    }
-
     private final class PrintersAdapter extends BaseAdapter
             implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>, Filterable {
         private final Object mLock = new Object();
@@ -568,7 +559,7 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
                 subtitleView.setVisibility(View.GONE);
             }
 
-            ImageView moreInfoView = (ImageView) convertView.findViewById(R.id.more_info);
+            LinearLayout moreInfoView = (LinearLayout) convertView.findViewById(R.id.more_info);
             if (printer.getInfoIntent() != null) {
                 moreInfoView.setVisibility(View.VISIBLE);
                 moreInfoView.setOnClickListener(new OnClickListener() {
index 8240fc1..44bdf0c 100644 (file)
@@ -21,23 +21,19 @@ import android.app.LoaderManager.LoaderCallbacks;
 import android.content.ActivityNotFoundException;
 import android.content.AsyncTaskLoader;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.Loader;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.database.ContentObserver;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
 import android.print.PrintJob;
 import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.print.PrintManager;
 import android.print.PrintManager.PrintJobStateChangeListener;
+import android.print.PrintServicesLoader;
 import android.printservice.PrintServiceInfo;
 import android.provider.SearchIndexableResource;
 import android.provider.Settings;
@@ -53,7 +49,6 @@ import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.TextView;
 
-import com.android.internal.content.PackageMonitor;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.DialogCreatable;
 import com.android.settings.R;
@@ -74,18 +69,13 @@ public class PrintSettingsFragment extends ProfileSettingsPreferenceFragment
         implements DialogCreatable, Indexable, OnClickListener {
     public static final String TAG = "PrintSettingsFragment";
     private static final int LOADER_ID_PRINT_JOBS_LOADER = 1;
+    private static final int LOADER_ID_PRINT_SERVICES = 2;
 
     private static final String PRINT_JOBS_CATEGORY = "print_jobs_category";
     private static final String PRINT_SERVICES_CATEGORY = "print_services_category";
 
-    // Extras passed to sub-fragments.
-    static final String EXTRA_PREFERENCE_KEY = "EXTRA_PREFERENCE_KEY";
     static final String EXTRA_CHECKED = "EXTRA_CHECKED";
     static final String EXTRA_TITLE = "EXTRA_TITLE";
-    static final String EXTRA_SETTINGS_TITLE = "EXTRA_SETTINGS_TITLE";
-    static final String EXTRA_SETTINGS_COMPONENT_NAME = "EXTRA_SETTINGS_COMPONENT_NAME";
-    static final String EXTRA_ADD_PRINTERS_TITLE = "EXTRA_ADD_PRINTERS_TITLE";
-    static final String EXTRA_ADD_PRINTERS_COMPONENT_NAME = "EXTRA_ADD_PRINTERS_COMPONENT_NAME";
     static final String EXTRA_SERVICE_COMPONENT_NAME = "EXTRA_SERVICE_COMPONENT_NAME";
 
     static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
@@ -93,29 +83,14 @@ public class PrintSettingsFragment extends ProfileSettingsPreferenceFragment
     private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME =
             "EXTRA_PRINT_SERVICE_COMPONENT_NAME";
 
-    private static final int ORDER_LAST = 1000;
-
-    private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void dispatchMessage(Message msg) {
-            updateServicesPreferences();
-        }
-    };
-
-    private final SettingsContentObserver mSettingsContentObserver =
-            new SettingsContentObserver(mHandler) {
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            updateServicesPreferences();
-        }
-    };
+    private static final int ORDER_LAST = Preference.DEFAULT_ORDER - 1;
 
     private PreferenceCategory mActivePrintJobsCategory;
     private PreferenceCategory mPrintServicesCategory;
 
     private PrintJobsController mPrintJobsController;
+    private PrintServicesController mPrintServicesController;
+
     private Button mAddNewServiceButton;
 
     @Override
@@ -140,24 +115,23 @@ public class PrintSettingsFragment extends ProfileSettingsPreferenceFragment
         getPreferenceScreen().removePreference(mActivePrintJobsCategory);
 
         mPrintJobsController = new PrintJobsController();
-        getActivity().getLoaderManager().initLoader(LOADER_ID_PRINT_JOBS_LOADER,
-                null, mPrintJobsController);
+        getActivity().getLoaderManager().initLoader(LOADER_ID_PRINT_JOBS_LOADER, null,
+                mPrintJobsController);
+
+        mPrintServicesController = new PrintServicesController();
+        getActivity().getLoaderManager().initLoader(LOADER_ID_PRINT_SERVICES, null,
+                mPrintServicesController);
     }
 
     @Override
     public void onStart() {
         super.onStart();
-        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
-        mSettingsContentObserver.register(getContentResolver());
-        updateServicesPreferences();
         setHasOptionsMenu(true);
         startSubSettingsIfNeeded();
     }
 
     @Override
     public void onStop() {
-        mSettingsPackageMonitor.unregister();
-        mSettingsContentObserver.unregister(getContentResolver());
         super.onStop();
     }
 
@@ -187,94 +161,80 @@ public class PrintSettingsFragment extends ProfileSettingsPreferenceFragment
         return Settings.ACTION_PRINT_SETTINGS;
     }
 
-    private void updateServicesPreferences() {
-        if (getPreferenceScreen().findPreference(PRINT_SERVICES_CATEGORY) == null) {
-            getPreferenceScreen().addPreference(mPrintServicesCategory);
-        } else {
-            // Since services category is auto generated we have to do a pass
-            // to generate it since services can come and go.
-            mPrintServicesCategory.removeAll();
+    /**
+     * Adds preferences for all print services to the {@value PRINT_SERVICES_CATEGORY} cathegory.
+     */
+    private final class PrintServicesController implements
+           LoaderCallbacks<List<PrintServiceInfo>> {
+        @Override
+        public Loader<List<PrintServiceInfo>> onCreateLoader(int id, Bundle args) {
+            PrintManager printManager =
+                    (PrintManager) getContext().getSystemService(Context.PRINT_SERVICE);
+            if (printManager != null) {
+                return new PrintServicesLoader(printManager, getContext(),
+                        PrintManager.ALL_SERVICES);
+            } else {
+                return null;
+            }
         }
 
-        List<ComponentName> disabledServices = PrintSettingsUtils
-                .readDisabledPrintServices(getActivity());
-
-        final PackageManager pm = getActivity().getPackageManager();
+        @Override
+        public void onLoadFinished(Loader<List<PrintServiceInfo>> loader,
+                List<PrintServiceInfo> services) {
+            if (services.isEmpty()) {
+                getPreferenceScreen().removePreference(mPrintServicesCategory);
+                return;
+            } else if (getPreferenceScreen().findPreference(PRINT_SERVICES_CATEGORY) == null) {
+                getPreferenceScreen().addPreference(mPrintServicesCategory);
+            }
 
-        List<ResolveInfo> installedServices = pm
-                .queryIntentServices(
-                        new Intent(android.printservice.PrintService.SERVICE_INTERFACE),
-                        PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+            mPrintServicesCategory.removeAll();
+            PackageManager pm = getActivity().getPackageManager();
 
-        final int installedServiceCount = installedServices.size();
-        for (int i = 0; i < installedServiceCount; i++) {
-            ResolveInfo installedService = installedServices.get(i);
+            final int numServices = services.size();
+            for (int i = 0; i < numServices; i++) {
+                PrintServiceInfo service = services.get(i);
+                PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
+                        getActivity());
 
-            PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
-                    getActivity());
+                String title = service.getResolveInfo().loadLabel(pm).toString();
+                preference.setTitle(title);
 
-            String title = installedService.loadLabel(getPackageManager()).toString();
-            preference.setTitle(title);
+                ComponentName componentName = service.getComponentName();
+                preference.setKey(componentName.flattenToString());
 
-            ComponentName componentName = new ComponentName(
-                    installedService.serviceInfo.packageName,
-                    installedService.serviceInfo.name);
-            preference.setKey(componentName.flattenToString());
+                preference.setOrder(Math.min(ORDER_LAST - 1, componentName.hashCode()));
+                preference.setFragment(PrintServiceSettingsFragment.class.getName());
+                preference.setPersistent(false);
 
-            preference.setOrder(i);
-            preference.setFragment(PrintServiceSettingsFragment.class.getName());
-            preference.setPersistent(false);
+                if (service.isEnabled()) {
+                    preference.setSummary(getString(R.string.print_feature_state_on));
+                } else {
+                    preference.setSummary(getString(R.string.print_feature_state_off));
+                }
 
-            final boolean serviceEnabled = !disabledServices.contains(componentName);
-            if (serviceEnabled) {
-                preference.setSummary(getString(R.string.print_feature_state_on));
-            } else {
-                preference.setSummary(getString(R.string.print_feature_state_off));
-            }
+                Drawable drawable = service.getResolveInfo().loadIcon(pm);
+                if (drawable != null) {
+                    preference.setIcon(drawable);
+                }
 
-            final Drawable drawable = installedService.loadIcon(pm);
-            if (drawable != null) {
-                preference.setIcon(drawable);
-            }
+                Bundle extras = preference.getExtras();
+                extras.putBoolean(EXTRA_CHECKED, service.isEnabled());
+                extras.putString(EXTRA_TITLE, title);
+                extras.putString(EXTRA_SERVICE_COMPONENT_NAME, componentName.flattenToString());
 
-            Bundle extras = preference.getExtras();
-            extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
-            extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
-            extras.putString(EXTRA_TITLE, title);
-
-            PrintServiceInfo printServiceInfo = PrintServiceInfo.create(
-                    installedService, getActivity());
-
-            String settingsClassName = printServiceInfo.getSettingsActivityName();
-            if (!TextUtils.isEmpty(settingsClassName)) {
-                extras.putString(EXTRA_SETTINGS_TITLE,
-                        getString(R.string.print_menu_item_settings));
-                extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
-                        new ComponentName(installedService.serviceInfo.packageName,
-                                settingsClassName).flattenToString());
+                mPrintServicesCategory.addPreference(preference);
             }
 
-            String addPrinterClassName = printServiceInfo.getAddPrintersActivityName();
-            if (!TextUtils.isEmpty(addPrinterClassName)) {
-                extras.putString(EXTRA_ADD_PRINTERS_TITLE,
-                        getString(R.string.print_menu_item_add_printers));
-                extras.putString(EXTRA_ADD_PRINTERS_COMPONENT_NAME,
-                        new ComponentName(installedService.serviceInfo.packageName,
-                                addPrinterClassName).flattenToString());
+            Preference addNewServicePreference = newAddServicePreferenceOrNull();
+            if (addNewServicePreference != null) {
+                mPrintServicesCategory.addPreference(addNewServicePreference);
             }
-
-            extras.putString(EXTRA_SERVICE_COMPONENT_NAME, componentName.flattenToString());
-
-            mPrintServicesCategory.addPreference(preference);
         }
 
-        if (mPrintServicesCategory.getPreferenceCount() == 0) {
+        @Override
+        public void onLoaderReset(Loader<List<PrintServiceInfo>> loader) {
             getPreferenceScreen().removePreference(mPrintServicesCategory);
-        } else {
-            final Preference addNewServicePreference = newAddServicePreferenceOrNull();
-            if (addNewServicePreference != null) {
-                mPrintServicesCategory.addPreference(addNewServicePreference);
-            }
         }
     }
 
@@ -329,48 +289,7 @@ public class PrintSettingsFragment extends ProfileSettingsPreferenceFragment
         }
     }
 
-    private class SettingsPackageMonitor extends PackageMonitor {
-        @Override
-        public void onPackageAdded(String packageName, int uid) {
-            mHandler.obtainMessage().sendToTarget();
-        }
-
-        @Override
-        public void onPackageAppeared(String packageName, int reason) {
-            mHandler.obtainMessage().sendToTarget();
-        }
-
-        @Override
-        public void onPackageDisappeared(String packageName, int reason) {
-            mHandler.obtainMessage().sendToTarget();
-        }
-
-        @Override
-        public void onPackageRemoved(String packageName, int uid) {
-            mHandler.obtainMessage().sendToTarget();
-        }
-    }
-
-    private static abstract class SettingsContentObserver extends ContentObserver {
-
-        public SettingsContentObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void register(ContentResolver contentResolver) {
-            contentResolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.DISABLED_PRINT_SERVICES), false, this);
-        }
-
-        public void unregister(ContentResolver contentResolver) {
-            contentResolver.unregisterContentObserver(this);
-        }
-
-        @Override
-        public abstract void onChange(boolean selfChange, Uri uri);
-    }
-
-    private final class PrintJobsController implements LoaderCallbacks<List<PrintJobInfo>> {
+     private final class PrintJobsController implements LoaderCallbacks<List<PrintJobInfo>> {
 
         @Override
         public Loader<List<PrintJobInfo>> onCreateLoader(int id, Bundle args) {
@@ -661,8 +580,10 @@ public class PrintSettingsFragment extends ProfileSettingsPreferenceFragment
             data.screenTitle = screenTitle;
             indexables.add(data);
 
-            // Indexing all services, regardless if enabled.
-            List<PrintServiceInfo> services = printManager.getInstalledPrintServices();
+            // Indexing all services, regardless if enabled. Please note that the index will not be
+            // updated until this function is called again
+            List<PrintServiceInfo> services =
+                    printManager.getPrintServices(PrintManager.ALL_SERVICES);
             final int serviceCount = services.size();
             for (int i = 0; i < serviceCount; i++) {
                 PrintServiceInfo service = services.get(i);
diff --git a/src/com/android/settings/print/PrintSettingsUtils.java b/src/com/android/settings/print/PrintSettingsUtils.java
deleted file mode 100644 (file)
index 87f26be..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.print;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.text.TextUtils.SimpleStringSplitter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Helper methods for reading and writing to print settings.
- */
-public class PrintSettingsUtils {
-
-    private static final char DISABLED_PRINT_SERVICES_SEPARATOR = ':';
-
-    private PrintSettingsUtils() {
-        /* do nothing */
-    }
-
-    public static List<ComponentName> readDisabledPrintServices(Context context) {
-        List<ComponentName> disabledServices = new ArrayList<ComponentName>();
-
-        String disabledServicesSetting = Settings.Secure.getString(context
-                .getContentResolver(), Settings.Secure.DISABLED_PRINT_SERVICES);
-        if (TextUtils.isEmpty(disabledServicesSetting)) {
-            return disabledServices;
-        }
-
-        SimpleStringSplitter colonSplitter = new SimpleStringSplitter(
-                DISABLED_PRINT_SERVICES_SEPARATOR);
-        colonSplitter.setString(disabledServicesSetting);
-
-        while (colonSplitter.hasNext()) {
-            String componentNameString = colonSplitter.next();
-            ComponentName disabledService = ComponentName.unflattenFromString(
-                    componentNameString);
-            if (disabledService != null) {
-                disabledServices.add(disabledService);
-            }
-        }
-
-        return disabledServices;
-    }
-
-    public static void writeDisabledPrintServices(Context context,
-            List<ComponentName> services) {
-        StringBuilder builder = new StringBuilder();
-        final int serviceCount = services.size();
-        for (int i = 0; i < serviceCount; i++) {
-            ComponentName service = services.get(i);
-            if (builder.length() > 0) {
-                builder.append(DISABLED_PRINT_SERVICES_SEPARATOR);
-            }
-            builder.append(service.flattenToString());
-        }
-        Settings.Secure.putString(context.getContentResolver(),
-                Settings.Secure.DISABLED_PRINT_SERVICES,
-                builder.toString());
-    }
-}
index 05880f0..6753a76 100644 (file)
@@ -18,20 +18,24 @@ package com.android.settings.search;
 
 import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.Activity;
+import android.app.LoaderManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.Loader;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.database.ContentObserver;
 import android.hardware.input.InputManager;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.UserHandle;
 import android.print.PrintManager;
-import android.printservice.PrintService;
+import android.print.PrintServicesLoader;
 import android.printservice.PrintServiceInfo;
 import android.provider.UserDictionary;
 import android.view.accessibility.AccessibilityManager;
@@ -47,7 +51,8 @@ import java.util.ArrayList;
 import java.util.List;
 
 public final class DynamicIndexableContentMonitor extends PackageMonitor implements
-        InputManager.InputDeviceListener {
+        InputManager.InputDeviceListener,
+        LoaderManager.LoaderCallbacks<List<PrintServiceInfo>> {
 
     private static final long DELAY_PROCESS_PACKAGE_CHANGE = 2000;
 
@@ -55,7 +60,6 @@ public final class DynamicIndexableContentMonitor extends PackageMonitor impleme
     private static final int MSG_PACKAGE_UNAVAILABLE = 2;
 
     private final List<String> mAccessibilityServices = new ArrayList<String>();
-    private final List<String> mPrintServices = new ArrayList<String>();
     private final List<String> mImeServices = new ArrayList<String>();
 
     private final Handler mHandler = new Handler() {
@@ -79,7 +83,6 @@ public final class DynamicIndexableContentMonitor extends PackageMonitor impleme
             new UserDictionaryContentObserver(mHandler);
 
     private Context mContext;
-    private boolean mHasFeaturePrinting;
     private boolean mHasFeatureIme;
 
     private static Intent getAccessibilityServiceIntent(String packageName) {
@@ -88,22 +91,16 @@ public final class DynamicIndexableContentMonitor extends PackageMonitor impleme
         return intent;
     }
 
-    private static Intent getPrintServiceIntent(String packageName) {
-        final Intent intent = new Intent(PrintService.SERVICE_INTERFACE);
-        intent.setPackage(packageName);
-        return intent;
-    }
-
     private static Intent getIMEServiceIntent(String packageName) {
         final Intent intent = new Intent("android.view.InputMethod");
         intent.setPackage(packageName);
         return intent;
     }
 
-    public void register(Context context) {
-        mContext = context;
+    public void register(Activity activity, int loaderId) {
+        mContext = activity;
 
-        mHasFeaturePrinting = mContext.getPackageManager().hasSystemFeature(
+        boolean hasFeaturePrinting = mContext.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_PRINTING);
         mHasFeatureIme = mContext.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_INPUT_METHODS);
@@ -123,20 +120,8 @@ public final class DynamicIndexableContentMonitor extends PackageMonitor impleme
             mAccessibilityServices.add(resolveInfo.serviceInfo.packageName);
         }
 
-        if (mHasFeaturePrinting) {
-            // Cache print service packages to know when they go away.
-            PrintManager printManager = (PrintManager)
-                    mContext.getSystemService(Context.PRINT_SERVICE);
-            List<PrintServiceInfo> printServices = printManager.getInstalledPrintServices();
-            final int serviceCount = printServices.size();
-            for (int i = 0; i < serviceCount; i++) {
-                PrintServiceInfo printService = printServices.get(i);
-                ResolveInfo resolveInfo = printService.getResolveInfo();
-                if (resolveInfo == null || resolveInfo.serviceInfo == null) {
-                    continue;
-                }
-                mPrintServices.add(resolveInfo.serviceInfo.packageName);
-            }
+        if (hasFeaturePrinting) {
+            activity.getLoaderManager().initLoader(loaderId, null, this);
         }
 
         // Cache IME service packages to know when they go away.
@@ -158,12 +143,12 @@ public final class DynamicIndexableContentMonitor extends PackageMonitor impleme
         }
 
         // Watch for input device changes.
-        InputManager inputManager = (InputManager) context.getSystemService(
+        InputManager inputManager = (InputManager) activity.getSystemService(
                 Context.INPUT_SERVICE);
         inputManager.registerInputDeviceListener(this, mHandler);
 
         // Start tracking packages.
-        register(context, Looper.getMainLooper(), UserHandle.CURRENT, false);
+        register(activity, Looper.getMainLooper(), UserHandle.CURRENT, false);
     }
 
     public void unregister() {
@@ -179,7 +164,6 @@ public final class DynamicIndexableContentMonitor extends PackageMonitor impleme
         }
 
         mAccessibilityServices.clear();
-        mPrintServices.clear();
         mImeServices.clear();
     }
 
@@ -242,18 +226,6 @@ public final class DynamicIndexableContentMonitor extends PackageMonitor impleme
             }
         }
 
-        if (mHasFeaturePrinting) {
-            if (!mPrintServices.contains(packageName)) {
-                final Intent intent = getPrintServiceIntent(packageName);
-                List<?> services = mContext.getPackageManager().queryIntentServices(intent, 0);
-                if (services != null && !services.isEmpty()) {
-                    mPrintServices.add(packageName);
-                    Index.getInstance(mContext).updateFromClassNameResource(
-                            PrintSettingsFragment.class.getName(), false, true);
-                }
-            }
-        }
-
         if (mHasFeatureIme) {
             if (!mImeServices.contains(packageName)) {
                 Intent intent = getIMEServiceIntent(packageName);
@@ -275,15 +247,6 @@ public final class DynamicIndexableContentMonitor extends PackageMonitor impleme
                     AccessibilitySettings.class.getName(), true, true);
         }
 
-        if (mHasFeaturePrinting) {
-            final int printIndex = mPrintServices.indexOf(packageName);
-            if (printIndex >= 0) {
-                mPrintServices.remove(printIndex);
-                Index.getInstance(mContext).updateFromClassNameResource(
-                        PrintSettingsFragment.class.getName(), true, true);
-            }
-        }
-
         if (mHasFeatureIme) {
             final int imeIndex = mImeServices.indexOf(packageName);
             if (imeIndex >= 0) {
@@ -294,6 +257,25 @@ public final class DynamicIndexableContentMonitor extends PackageMonitor impleme
         }
     }
 
+    @Override
+    public Loader<List<PrintServiceInfo>> onCreateLoader(int id, Bundle args) {
+        return new PrintServicesLoader(
+                (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE), mContext,
+                PrintManager.ALL_SERVICES);
+    }
+
+    @Override
+    public void onLoadFinished(Loader<List<PrintServiceInfo>> loader,
+            List<PrintServiceInfo> services) {
+        Index.getInstance(mContext).updateFromClassNameResource(
+                PrintSettingsFragment.class.getName(), false, true);
+    }
+
+    @Override
+    public void onLoaderReset(Loader<List<PrintServiceInfo>> loader) {
+        // nothing to do
+    }
+
     private final class UserDictionaryContentObserver extends ContentObserver {
 
         public UserDictionaryContentObserver(Handler handler) {