From: Svetoslav Ganov Date: Mon, 23 Sep 2013 22:48:23 +0000 (-0700) Subject: Add print job settings screen. X-Git-Tag: android-x86-4.4-r1~47^2^2^2^2^2^2^2~1^2~1^2^2^2^2~1 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b4c83de0b32d35a814dd3fe93dba401f5ac34ec3;p=android-x86%2Fpackages-apps-Settings.git Add print job settings screen. Added a list of active print jobs to the main print settings screen. Selecting a print job from there leads to a print job settings screen with more information about the print job and actions to change the prit job state such as cancel and restart. bug:10935736 Change-Id: Idd6826a998309941c3d8478dafe4b039c8ca4f45 Conflicts: res/values/donottranslate.xml --- diff --git a/res/drawable-hdpi/ic_grayedout_printer.png b/res/drawable-hdpi/ic_grayedout_printer.png new file mode 100644 index 0000000000..5e54970d6b Binary files /dev/null and b/res/drawable-hdpi/ic_grayedout_printer.png differ diff --git a/res/drawable-mdpi/ic_grayedout_printer.png b/res/drawable-mdpi/ic_grayedout_printer.png new file mode 100644 index 0000000000..5e54970d6b Binary files /dev/null and b/res/drawable-mdpi/ic_grayedout_printer.png differ diff --git a/res/drawable-xhdpi/ic_grayedout_printer.png b/res/drawable-xhdpi/ic_grayedout_printer.png new file mode 100644 index 0000000000..5e54970d6b Binary files /dev/null and b/res/drawable-xhdpi/ic_grayedout_printer.png differ diff --git a/res/layout/empty_print_state.xml b/res/layout/empty_print_state.xml new file mode 100644 index 0000000000..135b3dd24d --- /dev/null +++ b/res/layout/empty_print_state.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + diff --git a/res/layout/empty_printers_list_service_enabled.xml b/res/layout/empty_printers_list_service_enabled.xml new file mode 100644 index 0000000000..78c8b43ec5 --- /dev/null +++ b/res/layout/empty_printers_list_service_enabled.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/print_job_summary.xml b/res/layout/print_job_summary.xml new file mode 100644 index 0000000000..d755de217f --- /dev/null +++ b/res/layout/print_job_summary.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + diff --git a/res/values/donottranslate.xml b/res/values/donottranslate.xml index 12697ceece..f290f38eba 100644 --- a/res/values/donottranslate.xml +++ b/res/values/donottranslate.xml @@ -35,5 +35,6 @@ market://search?q=print service - + + market://search?q=nfc payment diff --git a/res/values/strings.xml b/res/values/strings.xml index 370a811c22..5d86ccf462 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3453,11 +3453,32 @@ Searching for printers + + Service disabled + Print jobs - - Active print jobs + + Print job + + + Restart + + + Cancel + + + %1$s\n%2$s + + + Printing %1$s + + + Printer error %1$s + + + Printer blocked %1$s diff --git a/res/xml/print_job_settings.xml b/res/xml/print_job_settings.xml new file mode 100644 index 0000000000..a78cec1c25 --- /dev/null +++ b/res/xml/print_job_settings.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + diff --git a/res/xml/print_settings.xml b/res/xml/print_settings.xml index dc3196871b..8a29563734 100644 --- a/res/xml/print_settings.xml +++ b/res/xml/print_settings.xml @@ -17,4 +17,17 @@ + + + + + + + diff --git a/src/com/android/settings/print/PrintJobSettingsFragment.java b/src/com/android/settings/print/PrintJobSettingsFragment.java new file mode 100644 index 0000000000..99499c85ed --- /dev/null +++ b/src/com/android/settings/print/PrintJobSettingsFragment.java @@ -0,0 +1,213 @@ +/* + * 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.app.ActivityManager; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.preference.Preference; +import android.print.PrintJob; +import android.print.PrintJobId; +import android.print.PrintJobInfo; +import android.print.PrintManager; +import android.print.PrintManager.PrintJobStateChangeListener; +import android.text.TextUtils; +import android.text.format.DateUtils; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; + +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; + +import java.text.DateFormat; + +/** + * Fragment for management of a print job. + */ +public class PrintJobSettingsFragment extends SettingsPreferenceFragment { + private static final int MENU_ITEM_ID_CANCEL = 1; + private static final int MENU_ITEM_ID_RESTART = 2; + + private static final String PRINT_JOB_PREFERENCE = "print_job_preference"; + private static final String PRINT_JOB_MESSAGE_PREFERENCE = "print_job_message_preference"; + + private Drawable mListDivider; + + private final PrintJobStateChangeListener mPrintJobStateChangeListener = + new PrintJobStateChangeListener() { + @Override + public void onPrintJobsStateChanged(PrintJobId printJobId) { + updateUi(); + } + }; + + private PrintManager mPrintManager; + + private Preference mPrintJobPreference; + private Preference mMessagePreference; + + private PrintJobId mPrintJobId; + private PrintJob mPrintJob; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + addPreferencesFromResource(R.xml.print_job_settings); + mPrintJobPreference = findPreference(PRINT_JOB_PREFERENCE); + mMessagePreference = findPreference(PRINT_JOB_MESSAGE_PREFERENCE); + + mPrintManager = ((PrintManager) getActivity().getSystemService( + Context.PRINT_SERVICE)).getGlobalPrintManagerForUser( + ActivityManager.getCurrentUser()); + + getActivity().getActionBar().setTitle(R.string.print_print_job); + + processArguments(); + + setHasOptionsMenu(true); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getListView().setEnabled(false); + } + + @Override + public void onResume() { + super.onResume(); + mPrintManager.addPrintJobStateChangeListener( + mPrintJobStateChangeListener); + updateUi(); + } + + @Override + public void onPause() { + super.onPause(); + mPrintManager.removePrintJobStateChangeListener( + mPrintJobStateChangeListener); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + + MenuItem cancel = menu.add(0, MENU_ITEM_ID_CANCEL, Menu.NONE, + getString(R.string.print_cancel)); + cancel.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + + if (mPrintJob.isFailed()) { + MenuItem restart = menu.add(0, MENU_ITEM_ID_RESTART, Menu.NONE, + getString(R.string.print_restart)); + restart.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case MENU_ITEM_ID_CANCEL: { + mPrintJob.cancel(); + finish(); + return true; + } + + case MENU_ITEM_ID_RESTART: { + mPrintJob.restart(); + finish(); + return true; + } + } + + return super.onOptionsItemSelected(item); + } + + private void processArguments() { + mPrintJobId = (PrintJobId) getArguments().getParcelable( + PrintSettingsFragment.EXTRA_PRINT_JOB_ID); + if (mPrintJobId == null) { + finish(); + } + } + + private void updateUi() { + mPrintJob = mPrintManager.getPrintJob(mPrintJobId); + + if (mPrintJob == null) { + finish(); + } + + if (mPrintJob.isCancelled() || mPrintJob.isCompleted()) { + finish(); + } + + PrintJobInfo info = mPrintJob.getInfo(); + + switch (info.getState()) { + case PrintJobInfo.STATE_QUEUED: + case PrintJobInfo.STATE_STARTED: { + mPrintJobPreference.setTitle(getString( + R.string.print_printing_state_title_template, info.getLabel())); + } break; + + case PrintJobInfo.STATE_FAILED: { + mPrintJobPreference.setTitle(getString( + R.string.print_failed_state_title_template, info.getLabel())); + } break; + + case PrintJobInfo.STATE_BLOCKED: { + mPrintJobPreference.setTitle(getString( + R.string.print_blocked_state_title_template, info.getLabel())); + } break; + } + + mPrintJobPreference.setSummary(getString(R.string.print_job_summary, + info.getPrinterName(), DateUtils.formatSameDayTime( + info.getCreationTime(), info.getCreationTime(), DateFormat.SHORT, + DateFormat.SHORT))); + + switch (info.getState()) { + case PrintJobInfo.STATE_QUEUED: + case PrintJobInfo.STATE_STARTED: { + mPrintJobPreference.setIcon(com.android.internal.R.drawable.ic_print); + } break; + + case PrintJobInfo.STATE_FAILED: + case PrintJobInfo.STATE_BLOCKED: { + mPrintJobPreference.setIcon(com.android.internal.R.drawable.ic_print_error); + } break; + } + + String stateReason = info.getStateReason(); + if (!TextUtils.isEmpty(stateReason)) { + if (getPreferenceScreen().findPreference(PRINT_JOB_MESSAGE_PREFERENCE) == null) { + getPreferenceScreen().addPreference(mMessagePreference); + } + mMessagePreference.setSummary(stateReason); + getListView().setDivider(null); + } else { + getPreferenceScreen().removePreference(mMessagePreference); + getListView().setDivider(mListDivider); + } + + getActivity().invalidateOptionsMenu(); + } +} diff --git a/src/com/android/settings/print/PrintServiceSettingsFragment.java b/src/com/android/settings/print/PrintServiceSettingsFragment.java index 87db29bb5b..d2d8525abd 100644 --- a/src/com/android/settings/print/PrintServiceSettingsFragment.java +++ b/src/com/android/settings/print/PrintServiceSettingsFragment.java @@ -27,15 +27,12 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.Loader; -import android.content.pm.ActivityInfo; import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; import android.database.ContentObserver; import android.database.DataSetObserver; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceActivity; @@ -54,8 +51,10 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; +import android.widget.CompoundButton; import android.widget.Filter; import android.widget.Filterable; +import android.widget.ListView; import android.widget.SearchView; import android.widget.TextView; @@ -69,6 +68,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import android.widget.CompoundButton.OnCheckedChangeListener; /** * Fragment with print service settings. */ @@ -83,7 +83,7 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment new SettingsContentObserver(new Handler()) { @Override public void onChange(boolean selfChange, Uri uri) { - updateForServiceEnabledState(); + updateUiForServiceState(); } }; @@ -108,15 +108,15 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment } }; - protected ToggleSwitch mToggleSwitch; + private ToggleSwitch mToggleSwitch; - protected String mPreferenceKey; + private String mPreferenceKey; - protected CharSequence mSettingsTitle; - protected Intent mSettingsIntent; + private CharSequence mSettingsTitle; + private Intent mSettingsIntent; - protected CharSequence mAddPrintersTitle; - protected Intent mAddPrintersIntent; + private CharSequence mAddPrintersTitle; + private Intent mAddPrintersIntent; private CharSequence mEnableWarningTitle; private CharSequence mEnableWarningMessage; @@ -135,9 +135,10 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment @Override public void onResume() { - mSettingsContentObserver.register(getContentResolver()); super.onResume(); - updateForServiceEnabledState(); + mSettingsContentObserver.register(getContentResolver()); + updateEmptyView(); + updateUiForServiceState(); } @Override @@ -149,12 +150,8 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - installActionBarToggleSwitch(); - processArguments(getArguments()); - mPrintersAdapter = new PrintersAdapter(); - mPrintersAdapter.registerDataSetObserver(mDataObserver); - getListView().setAdapter(mPrintersAdapter); - updateForServiceEnabledState(); + initComponents(); + updateUiForArguments(); } @Override @@ -221,7 +218,40 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment } } - private void updateForServiceEnabledState() { + private void updateEmptyView() { + ListView listView = getListView(); + ViewGroup contentRoot = (ViewGroup) listView.getParent(); + View emptyView = listView.getEmptyView(); + if (!mToggleSwitch.isChecked()) { + if (emptyView != null + && emptyView.getId() != R.id.empty_printers_list_service_disabled) { + contentRoot.removeView(emptyView); + emptyView = null; + } + if (emptyView == null) { + emptyView = getActivity().getLayoutInflater().inflate( + R.layout.empty_print_state, contentRoot, false); + TextView textView = (TextView) emptyView.findViewById(R.id.message); + textView.setText(R.string.print_service_disabled); + contentRoot.addView(emptyView); + listView.setEmptyView(emptyView); + } + } else if (mPrintersAdapter.getUnfilteredCount() <= 0) { + if (emptyView != null + && emptyView.getId() != R.id.empty_printers_list_service_enabled) { + contentRoot.removeView(emptyView); + emptyView = null; + } + if (emptyView == null) { + emptyView = getActivity().getLayoutInflater().inflate( + R.layout.empty_printers_list_service_enabled, contentRoot, false); + contentRoot.addView(emptyView); + listView.setEmptyView(emptyView); + } + } + } + + private void updateUiForServiceState() { List services = SettingsUtils.readEnabledPrintServices(getActivity()); mServiceEnabled = services.contains(mComponentName); if (mServiceEnabled) { @@ -234,7 +264,10 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment getActivity().invalidateOptionsMenu(); } - private void installActionBarToggleSwitch() { + private void initComponents() { + mPrintersAdapter = new PrintersAdapter(); + mPrintersAdapter.registerDataSetObserver(mDataObserver); + mToggleSwitch = createAndAddActionBarToggleSwitch(getActivity()); mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() { @Override @@ -253,9 +286,20 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment return false; } }); + mToggleSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + updateEmptyView(); + } + }); + + getListView().setEnabled(false); + getListView().setAdapter(mPrintersAdapter); } - private void processArguments(Bundle arguments) { + private void updateUiForArguments() { + Bundle arguments = getArguments(); + // Key. mPreferenceKey = arguments.getString(PrintSettingsFragment.EXTRA_PREFERENCE_KEY); @@ -381,22 +425,21 @@ 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(Settings.Secure.getUriFor( - Settings.Secure.ENABLED_PRINT_SERVICES), false, this); - } + public SettingsContentObserver(Handler handler) { + super(handler); + } - public void unregister(ContentResolver contentResolver) { - contentResolver.unregisterContentObserver(this); - } + public void register(ContentResolver contentResolver) { + contentResolver.registerContentObserver(Settings.Secure.getUriFor( + Settings.Secure.ENABLED_PRINT_SERVICES), false, this); + } - @Override - public abstract void onChange(boolean selfChange, Uri uri); + public void unregister(ContentResolver contentResolver) { + contentResolver.unregisterContentObserver(this); + } + @Override + public abstract void onChange(boolean selfChange, Uri uri); } private final class PrintersAdapter extends BaseAdapter @@ -415,6 +458,7 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment public void disable() { getLoaderManager().destroyLoader(LOADER_ID_PRINTERS_LOADER); + mPrinters.clear(); } public int getUnfilteredCount() { @@ -560,7 +604,7 @@ public class PrintServiceSettingsFragment extends SettingsPreferenceFragment private static final String LOG_TAG = "PrintersLoader"; - private static final boolean DEBUG = true && Build.IS_DEBUGGABLE; + private static final boolean DEBUG = false; private final Map mPrinters = new LinkedHashMap(); diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java index 49f0e658b5..84865c339a 100644 --- a/src/com/android/settings/print/PrintSettingsFragment.java +++ b/src/com/android/settings/print/PrintSettingsFragment.java @@ -16,10 +16,14 @@ package com.android.settings.print; +import android.app.ActivityManager; +import android.app.LoaderManager.LoaderCallbacks; +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; @@ -28,14 +32,23 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.preference.Preference; +import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; +import android.print.PrintJob; +import android.print.PrintJobId; +import android.print.PrintJobInfo; +import android.print.PrintManager; +import android.print.PrintManager.PrintJobStateChangeListener; import android.printservice.PrintServiceInfo; import android.provider.Settings; import android.text.TextUtils; +import android.text.format.DateUtils; +import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.view.ViewGroup; import android.widget.Switch; import android.widget.TextView; @@ -44,6 +57,8 @@ import com.android.settings.DialogCreatable; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; +import java.text.DateFormat; +import java.util.ArrayList; import java.util.List; /** @@ -53,17 +68,24 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements static final char ENABLED_PRINT_SERVICES_SEPARATOR = ':'; + private static final int LOADER_ID_PRINT_JOBS_LOADER = 1; + + 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 = "preference_key"; - static final String EXTRA_CHECKED = "checked"; - static final String EXTRA_TITLE = "title"; - static final String EXTRA_ENABLE_WARNING_TITLE = "enable_warning_title"; - static final String EXTRA_ENABLE_WARNING_MESSAGE = "enable_warning_message"; - static final String EXTRA_SETTINGS_TITLE = "settings_title"; - static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name"; - static final String EXTRA_ADD_PRINTERS_TITLE = "add_printers_title"; - static final String EXTRA_ADD_PRINTERS_COMPONENT_NAME = "add_printers_component_name"; - static final String EXTRA_SERVICE_COMPONENT_NAME = "service_component_name"; + 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_ENABLE_WARNING_TITLE = "EXTRA_ENABLE_WARNING_TITLE"; + static final String EXTRA_ENABLE_WARNING_MESSAGE = "EXTRA_ENABLE_WARNING_MESSAGE"; + 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"; private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME = "EXTRA_PRINT_SERVICE_COMPONENT_NAME"; @@ -85,13 +107,27 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements } }; - private Preference mNoServicesMessagePreference; + private PreferenceCategory mActivePrintJobsCategory; + private PreferenceCategory mPrintServicesCategory; + + private PrintJobsController mPrintJobsController; + + private String mPrintJobPreferenceToActivate; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); addPreferencesFromResource(R.xml.print_settings); - getActivity().getActionBar().setTitle(R.string.print_settings_title); + + mActivePrintJobsCategory = (PreferenceCategory) findPreference( + PRINT_JOBS_CATEGORY); + mPrintServicesCategory= (PreferenceCategory) findPreference( + PRINT_SERVICES_CATEGORY); + getPreferenceScreen().removePreference(mActivePrintJobsCategory); + + mPrintJobsController = new PrintJobsController(); + getActivity().getLoaderManager().initLoader(LOADER_ID_PRINT_JOBS_LOADER, + null, mPrintJobsController); } @Override @@ -100,8 +136,8 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false); mSettingsContentObserver.register(getContentResolver()); updateServicesPreferences(); - startPrintServiceSettingsIfNeeded(); setHasOptionsMenu(true); + startSubSettingsIfNeeded(); } @Override @@ -120,10 +156,26 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements Uri.parse(getString(R.string.download_print_service_query)))); } + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + ViewGroup contentRoot = (ViewGroup) getListView().getParent(); + View emptyView = getActivity().getLayoutInflater().inflate( + R.layout.empty_print_state, contentRoot, false); + TextView textView = (TextView) emptyView.findViewById(R.id.message); + textView.setText(R.string.print_no_services_installed); + contentRoot.addView(emptyView); + getListView().setEmptyView(emptyView); + } + private void updateServicesPreferences() { - // Since services category is auto generated we have to do a pass - // to generate it since services can come and go. - getPreferenceScreen().removeAll(); + 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(); + } List enabledServices = SettingsUtils .readEnabledPrintServices(getActivity()); @@ -194,30 +246,15 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements extras.putString(EXTRA_SERVICE_COMPONENT_NAME, componentName.flattenToString()); - getPreferenceScreen().addPreference(preference); + mPrintServicesCategory.addPreference(preference); } - if (getPreferenceScreen().getPreferenceCount() == 0) { - if (mNoServicesMessagePreference == null) { - mNoServicesMessagePreference = new Preference(getActivity()) { - @Override - protected void onBindView(View view) { - super.onBindView(view); - TextView summaryView = (TextView) view.findViewById(R.id.summary); - String title = getString(R.string.print_no_services_installed); - summaryView.setText(title); - } - }; - mNoServicesMessagePreference.setPersistent(false); - mNoServicesMessagePreference.setLayoutResource( - R.layout.text_description_preference); - mNoServicesMessagePreference.setSelectable(false); - } - getPreferenceScreen().addPreference(mNoServicesMessagePreference); + if (mPrintServicesCategory.getPreferenceCount() == 0) { + getPreferenceScreen().removePreference(mPrintServicesCategory); } } - private void startPrintServiceSettingsIfNeeded() { + private void startSubSettingsIfNeeded() { if (getArguments() == null) { return; } @@ -228,6 +265,19 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements if (prereference != null) { prereference.performClick(getPreferenceScreen()); } + } else { + String printJobId = getArguments().getString(EXTRA_PRINT_JOB_ID); + if (printJobId != null) { + getArguments().remove(EXTRA_PRINT_JOB_ID); + Preference preference = findPreference(printJobId); + if (preference != null) { + preference.performClick(getPreferenceScreen()); + } else { + // The preference not being present may mean the the print job + // loader has not completed so make a note and wait for the load. + mPrintJobPreferenceToActivate = printJobId; + } + } } } @@ -301,4 +351,207 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment implements @Override public abstract void onChange(boolean selfChange, Uri uri); } + + private final class PrintJobsController implements LoaderCallbacks> { + + @Override + public Loader> onCreateLoader(int id, Bundle args) { + if (id == LOADER_ID_PRINT_JOBS_LOADER) { + return new PrintJobsLoader(getActivity()); + } + return null; + } + + @Override + public void onLoadFinished(Loader> loader, + List printJobs) { + if (printJobs == null || printJobs.isEmpty()) { + getPreferenceScreen().removePreference(mActivePrintJobsCategory); + } else { + if (getPreferenceScreen().findPreference(PRINT_JOBS_CATEGORY) == null) { + getPreferenceScreen().addPreference(mActivePrintJobsCategory); + } + + mActivePrintJobsCategory.removeAll(); + + final int printJobCount = printJobs.size(); + for (int i = 0; i < printJobCount; i++) { + PrintJobInfo printJob = printJobs.get(i); + + PreferenceScreen preference = getPreferenceManager() + .createPreferenceScreen(getActivity()); + + preference.setPersistent(false); + preference.setFragment(PrintJobSettingsFragment.class.getName()); + preference.setKey(printJob.getId().flattenToString()); + + switch (printJob.getState()) { + case PrintJobInfo.STATE_QUEUED: + case PrintJobInfo.STATE_STARTED: { + preference.setTitle(getString( + R.string.print_printing_state_title_template, + printJob.getLabel())); + } break; + + case PrintJobInfo.STATE_FAILED: { + preference.setTitle(getString( + R.string.print_failed_state_title_template, + printJob.getLabel())); + } break; + + case PrintJobInfo.STATE_BLOCKED: { + preference.setTitle(getString( + R.string.print_blocked_state_title_template, + printJob.getLabel())); + } break; + } + + preference.setSummary(getString(R.string.print_job_summary, + printJob.getPrinterName(), DateUtils.formatSameDayTime( + printJob.getCreationTime(), printJob.getCreationTime(), + DateFormat.SHORT, DateFormat.SHORT))); + + switch (printJob.getState()) { + case PrintJobInfo.STATE_QUEUED: + case PrintJobInfo.STATE_STARTED: { + preference.setIcon(com.android.internal.R.drawable.ic_print); + } break; + + case PrintJobInfo.STATE_FAILED: + case PrintJobInfo.STATE_BLOCKED: { + preference.setIcon(com.android.internal.R.drawable.ic_print_error); + } break; + } + + Bundle extras = preference.getExtras(); + extras.putParcelable(EXTRA_PRINT_JOB_ID, printJob.getId()); + + mActivePrintJobsCategory.addPreference(preference); + } + + // If were waiting for creating a preference for a print + // job so we can start it - do that. + if (mPrintJobPreferenceToActivate != null) { + Preference preference = findPreference(mPrintJobPreferenceToActivate); + mPrintJobPreferenceToActivate = null; + if (preference != null) { + preference.performClick(getPreferenceScreen()); + } + } + } + } + + @Override + public void onLoaderReset(Loader> loader) { + getPreferenceScreen().removePreference(mActivePrintJobsCategory); + } + } + + private static final class PrintJobsLoader extends AsyncTaskLoader> { + + private static final String LOG_TAG = "PrintJobsLoader"; + + private static final boolean DEBUG = true; + + private List mPrintJobs = new ArrayList(); + + private final PrintManager mPrintManager; + + private PrintJobStateChangeListener mPrintJobStateChangeListener; + + public PrintJobsLoader(Context context) { + super(context); + mPrintManager = ((PrintManager) context.getSystemService( + Context.PRINT_SERVICE)).getGlobalPrintManagerForUser( + ActivityManager.getCurrentUser()); + } + + @Override + public void deliverResult(List printJobs) { + if (isStarted()) { + super.deliverResult(printJobs); + } + } + + @Override + protected void onStartLoading() { + if (DEBUG) { + Log.i(LOG_TAG, "onStartLoading()"); + } + // If we already have a result, deliver it immediately. + if (!mPrintJobs.isEmpty()) { + deliverResult(new ArrayList(mPrintJobs)); + } + // Start watching for changes. + if (mPrintJobStateChangeListener == null) { + mPrintJobStateChangeListener = new PrintJobStateChangeListener() { + @Override + public void onPrintJobsStateChanged(PrintJobId printJobId) { + onForceLoad(); + } + }; + mPrintManager.addPrintJobStateChangeListener( + mPrintJobStateChangeListener); + } + // If the data changed or we have no data - load it now. + if (mPrintJobs.isEmpty()) { + onForceLoad(); + } + } + + @Override + protected void onStopLoading() { + if (DEBUG) { + Log.i(LOG_TAG, "onStopLoading()"); + } + // Cancel the load in progress if possible. + onCancelLoad(); + } + + @Override + protected void onReset() { + if (DEBUG) { + Log.i(LOG_TAG, "onReset()"); + } + // Stop loading. + onStopLoading(); + // Clear the cached result. + mPrintJobs.clear(); + // Stop watching for changes. + if (mPrintJobStateChangeListener != null) { + mPrintManager.removePrintJobStateChangeListener( + mPrintJobStateChangeListener); + mPrintJobStateChangeListener = null; + } + } + + @Override + public List loadInBackground() { + List printJobInfos = null; + List printJobs = mPrintManager.getPrintJobs(); + final int printJobCount = printJobs.size(); + for (int i = 0; i < printJobCount; i++) { + PrintJobInfo printJob = printJobs.get(i).getInfo(); + if (shouldShowToUser(printJob)) { + if (printJobInfos == null) { + printJobInfos = new ArrayList(); + } + printJobInfos.add(printJob); + } + } + return printJobInfos; + } + + private static boolean shouldShowToUser(PrintJobInfo printJob) { + switch (printJob.getState()) { + case PrintJobInfo.STATE_QUEUED: + case PrintJobInfo.STATE_STARTED: + case PrintJobInfo.STATE_BLOCKED: + case PrintJobInfo.STATE_FAILED: { + return true; + } + } + return false; + } + } }