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
This commit is contained in:
Svetoslav Ganov
2013-09-23 15:48:23 -07:00
committed by Svetoslav
parent 077f83a22c
commit bc2c3db8f9
13 changed files with 793 additions and 74 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/empty_printers_list_service_disabled"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dip"
android:src="@drawable/ic_grayedout_printer"
android:contentDescription="@string/print_service_disabled">
</ImageView>
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorSecondary">
</TextView>
</LinearLayout>
</FrameLayout>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/empty_printers_list_service_enabled"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dip"
android:src="@drawable/ic_grayedout_printer"
android:contentDescription="@string/print_searching_for_printers">
</ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorSecondary"
android:text="@string/print_searching_for_printers">
</TextView>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
style="@android:style/Widget.Holo.ProgressBar.Horizontal">
</ProgressBar>
</LinearLayout>
</FrameLayout>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dip"
android:layout_marginEnd="6dip"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="top|start"
android:orientation="vertical"
android:paddingEnd="?android:attr/scrollbarSize"
android:background="?android:attr/selectableItemBackground">
<View
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="?android:attr/listDivider">
</View>
<TextView android:id="@+android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary">
</TextView>
</LinearLayout>

View File

@@ -37,5 +37,4 @@
<string name="download_print_service_query">market://search?q=print service</string>
<!-- Default query string to search for a NFC payment service. -->
<string name="download_nfc_payment_service_query">market://search?q=nfc payment</string>
</resources>

View File

@@ -3453,11 +3453,32 @@
<!-- Title for the prompt if no printers are available and the system is searching for such. [CHAR LIMIT=50] -->
<string name="print_searching_for_printers">Searching for printers</string>
<!-- Title for the prompt if no printers are available because the print service is disabled. [CHAR LIMIT=50] -->
<string name="print_service_disabled">Service disabled</string>
<!-- Title for the menu item to open the print jobs screen. [CHAR LIMIT=25] -->
<string name="print_print_jobs">Print jobs</string>
<!-- Title for the print jobs screen. [CHAR LIMIT=25] -->
<string name="print_active_print_jobs">Active print jobs</string>
<!-- Title for the print job settings screen. [CHAR LIMIT=25] -->
<string name="print_print_job">Print job</string>
<!-- Title for the button to restart a print job. [CHAR LIMIT=25] -->
<string name="print_restart">Restart</string>
<!-- Title for the button to cancel a print job. [CHAR LIMIT=25] -->
<string name="print_cancel">Cancel</string>
<!-- Template for the summary of a print job. [CHAR LIMIT=25] -->
<string name="print_job_summary"><xliff:g id="printer">%1$s</xliff:g>\n<xliff:g id="time">%2$s</xliff:g></string>
<!-- Template for the label of the state for a ongoing print job. [CHAR LIMIT=25] -->
<string name="print_printing_state_title_template">Printing <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
<!-- Template for the label of the state for a failed print job. [CHAR LIMIT=25] -->
<string name="print_failed_state_title_template">Printer error <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
<!-- Template for the label of the state for a blocked print job. [CHAR LIMIT=25] -->
<string name="print_blocked_state_title_template">Printer blocked <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
<!-- App Fuel Gauge strings -->
<skip />

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/print_print_job">
<Preference
android:key="print_job_preference">
</Preference>
<Preference
android:key="print_job_message_preference"
android:layout="@layout/print_job_summary">
</Preference>
</PreferenceScreen>

View File

@@ -17,4 +17,17 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/print_settings_title">
<PreferenceCategory
android:key="print_jobs_category"
android:title="@string/print_print_jobs"
android:order="0">
</PreferenceCategory>
<PreferenceCategory
android:key="print_services_category"
android:title="@string/print_settings_title"
android:order="1">
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -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();
}
}

View File

@@ -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<ComponentName> 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 SettingsContentObserver(Handler handler) {
super(handler);
}
public void register(ContentResolver contentResolver) {
contentResolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.ENABLED_PRINT_SERVICES), false, this);
}
public void register(ContentResolver contentResolver) {
contentResolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.ENABLED_PRINT_SERVICES), false, this);
}
public void unregister(ContentResolver contentResolver) {
contentResolver.unregisterContentObserver(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<PrinterId, PrinterInfo> mPrinters =
new LinkedHashMap<PrinterId, PrinterInfo>();

View File

@@ -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<ComponentName> 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<List<PrintJobInfo>> {
@Override
public Loader<List<PrintJobInfo>> onCreateLoader(int id, Bundle args) {
if (id == LOADER_ID_PRINT_JOBS_LOADER) {
return new PrintJobsLoader(getActivity());
}
return null;
}
@Override
public void onLoadFinished(Loader<List<PrintJobInfo>> loader,
List<PrintJobInfo> 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<List<PrintJobInfo>> loader) {
getPreferenceScreen().removePreference(mActivePrintJobsCategory);
}
}
private static final class PrintJobsLoader extends AsyncTaskLoader<List<PrintJobInfo>> {
private static final String LOG_TAG = "PrintJobsLoader";
private static final boolean DEBUG = true;
private List <PrintJobInfo> mPrintJobs = new ArrayList<PrintJobInfo>();
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<PrintJobInfo> 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<PrintJobInfo>(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<PrintJobInfo> loadInBackground() {
List<PrintJobInfo> printJobInfos = null;
List<PrintJob> 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<PrintJobInfo>();
}
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;
}
}
}