am 6f688e87: am 8f34715b: Merge "Refactor how the print dialog activity is started." into klp-dev

* commit '6f688e879a2523393e8e0da072e1f62cb456276f':
  Refactor how the print dialog activity is started.
This commit is contained in:
Svetoslav
2013-10-11 10:06:03 -07:00
committed by Android Git Automerger
11 changed files with 333 additions and 246 deletions

View File

@ -165,7 +165,6 @@ LOCAL_SRC_FILES += \
core/java/android/print/ILayoutResultCallback.aidl \ core/java/android/print/ILayoutResultCallback.aidl \
core/java/android/print/IPrinterDiscoveryObserver.aidl \ core/java/android/print/IPrinterDiscoveryObserver.aidl \
core/java/android/print/IPrintDocumentAdapter.aidl \ core/java/android/print/IPrintDocumentAdapter.aidl \
core/java/android/print/IPrintClient.aidl \
core/java/android/print/IPrintJobStateChangeListener.aidl \ core/java/android/print/IPrintJobStateChangeListener.aidl \
core/java/android/print/IPrintManager.aidl \ core/java/android/print/IPrintManager.aidl \
core/java/android/print/IPrintSpooler.aidl \ core/java/android/print/IPrintSpooler.aidl \

View File

@ -183,6 +183,8 @@ $(call add-clean-step, rm -f $(PRODUCT_OUT)/system/media/video/*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/effects/) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/effects/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/framework-res_intermediates) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/framework-res_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrintClient.*)
# ************************************************ # ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************ # ************************************************

View File

@ -16,9 +16,9 @@
package android.print; package android.print;
import android.os.Bundle;
import android.print.IPrinterDiscoveryObserver; import android.print.IPrinterDiscoveryObserver;
import android.print.IPrintDocumentAdapter; import android.print.IPrintDocumentAdapter;
import android.print.IPrintClient;
import android.print.PrintJobId; import android.print.PrintJobId;
import android.print.IPrintJobStateChangeListener; import android.print.IPrintJobStateChangeListener;
import android.print.PrinterId; import android.print.PrinterId;
@ -34,9 +34,8 @@ import android.printservice.PrintServiceInfo;
interface IPrintManager { interface IPrintManager {
List<PrintJobInfo> getPrintJobInfos(int appId, int userId); List<PrintJobInfo> getPrintJobInfos(int appId, int userId);
PrintJobInfo getPrintJobInfo(in PrintJobId printJobId, int appId, int userId); PrintJobInfo getPrintJobInfo(in PrintJobId printJobId, int appId, int userId);
PrintJobInfo print(String printJobName, in IPrintClient client, Bundle print(String printJobName, in IPrintDocumentAdapter printAdapter,
in IPrintDocumentAdapter printAdapter, in PrintAttributes attributes, in PrintAttributes attributes, String packageName, int appId, int userId);
int appId, int userId);
void cancelPrintJob(in PrintJobId printJobId, int appId, int userId); void cancelPrintJob(in PrintJobId printJobId, int appId, int userId);
void restartPrintJob(in PrintJobId printJobId, int appId, int userId); void restartPrintJob(in PrintJobId printJobId, int appId, int userId);

View File

@ -18,8 +18,6 @@ package android.print;
import android.content.ComponentName; import android.content.ComponentName;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.print.IPrintDocumentAdapter;
import android.print.IPrintClient;
import android.print.IPrintSpoolerClient; import android.print.IPrintSpoolerClient;
import android.print.IPrintSpoolerCallbacks; import android.print.IPrintSpoolerCallbacks;
import android.print.PrinterInfo; import android.print.PrinterInfo;
@ -40,8 +38,7 @@ oneway interface IPrintSpooler {
int state, int appId, int sequence); int state, int appId, int sequence);
void getPrintJobInfo(in PrintJobId printJobId, IPrintSpoolerCallbacks callback, void getPrintJobInfo(in PrintJobId printJobId, IPrintSpoolerCallbacks callback,
int appId, int sequence); int appId, int sequence);
void createPrintJob(in PrintJobInfo printJob, in IPrintClient client, void createPrintJob(in PrintJobInfo printJob);
in IPrintDocumentAdapter printAdapter);
void setPrintJobState(in PrintJobId printJobId, int status, String stateReason, void setPrintJobState(in PrintJobId printJobId, int status, String stateReason,
IPrintSpoolerCallbacks callback, int sequence); IPrintSpoolerCallbacks callback, int sequence);
void setPrintJobTag(in PrintJobId printJobId, String tag, IPrintSpoolerCallbacks callback, void setPrintJobTag(in PrintJobId printJobId, String tag, IPrintSpoolerCallbacks callback,

View File

@ -60,8 +60,47 @@ public final class PrintManager {
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private static final int MSG_START_PRINT_JOB_CONFIG_ACTIVITY = 1; private static final int MSG_NOTIFY_PRINT_JOB_STATE_CHANGED = 1;
private static final int MSG_NOTIFY_PRINT_JOB_STATE_CHANGED = 2;
/**
* The action for launching the print dialog activity.
*
* @hide
*/
public static final String ACTION_PRINT_DIALOG = "android.print.PRINT_DIALOG";
/**
* Extra with the intent for starting the print dialog.
* <p>
* <strong>Type:</strong> {@link android.content.IntentSender}
* </p>
*
* @hide
*/
public static final String EXTRA_PRINT_DIALOG_INTENT =
"android.print.intent.extra.EXTRA_PRINT_DIALOG_INTENT";
/**
* Extra with a print job.
* <p>
* <strong>Type:</strong> {@link android.print.PrintJobInfo}
* </p>
*
* @hide
*/
public static final String EXTRA_PRINT_JOB =
"android.print.intent.extra.EXTRA_PRINT_JOB";
/**
* Extra with the print document adapter to be printed.
* <p>
* <strong>Type:</strong> {@link android.print.IPrintDocumentAdapter}
* </p>
*
* @hide
*/
public static final String EXTRA_PRINT_DOCUMENT_ADAPTER =
"android.print.intent.extra.EXTRA_PRINT_DOCUMENT_ADAPTER";
/** @hide */ /** @hide */
public static final int APP_ID_ANY = -2; public static final int APP_ID_ANY = -2;
@ -74,8 +113,6 @@ public final class PrintManager {
private final int mAppId; private final int mAppId;
private final PrintClient mPrintClient;
private final Handler mHandler; private final Handler mHandler;
private Map<PrintJobStateChangeListener, PrintJobStateChangeListenerWrapper> mPrintJobStateChangeListeners; private Map<PrintJobStateChangeListener, PrintJobStateChangeListenerWrapper> mPrintJobStateChangeListeners;
@ -103,24 +140,10 @@ public final class PrintManager {
mService = service; mService = service;
mUserId = userId; mUserId = userId;
mAppId = appId; mAppId = appId;
mPrintClient = new PrintClient(this);
mHandler = new Handler(context.getMainLooper(), null, false) { mHandler = new Handler(context.getMainLooper(), null, false) {
@Override @Override
public void handleMessage(Message message) { public void handleMessage(Message message) {
switch (message.what) { switch (message.what) {
case MSG_START_PRINT_JOB_CONFIG_ACTIVITY: {
SomeArgs args = (SomeArgs) message.obj;
Context context = (Context) args.arg1;
IntentSender intent = (IntentSender) args.arg2;
args.recycle();
try {
context.startIntentSender(intent, null, 0, 0, 0);
} catch (SendIntentException sie) {
Log.e(LOG_TAG, "Couldn't start print job config activity.", sie);
}
}
break;
case MSG_NOTIFY_PRINT_JOB_STATE_CHANGED: { case MSG_NOTIFY_PRINT_JOB_STATE_CHANGED: {
SomeArgs args = (SomeArgs) message.obj; SomeArgs args = (SomeArgs) message.obj;
PrintJobStateChangeListener listener = PrintJobStateChangeListener listener =
@ -128,8 +151,7 @@ public final class PrintManager {
PrintJobId printJobId = (PrintJobId) args.arg2; PrintJobId printJobId = (PrintJobId) args.arg2;
args.recycle(); args.recycle();
listener.onPrintJobStateChanged(printJobId); listener.onPrintJobStateChanged(printJobId);
} } break;
break;
} }
} }
}; };
@ -279,10 +301,20 @@ public final class PrintManager {
PrintDocumentAdapterDelegate delegate = new PrintDocumentAdapterDelegate(documentAdapter, PrintDocumentAdapterDelegate delegate = new PrintDocumentAdapterDelegate(documentAdapter,
mContext.getMainLooper()); mContext.getMainLooper());
try { try {
PrintJobInfo printJob = mService.print(printJobName, mPrintClient, delegate, Bundle result = mService.print(printJobName, delegate,
attributes, mAppId, mUserId); attributes, mContext.getPackageName(), mAppId, mUserId);
if (printJob != null) { if (result != null) {
return new PrintJob(printJob, this); PrintJobInfo printJob = result.getParcelable(EXTRA_PRINT_JOB);
IntentSender intent = result.getParcelable(EXTRA_PRINT_DIALOG_INTENT);
if (printJob == null || intent == null) {
return null;
}
try {
mContext.startIntentSender(intent, null, 0, 0, 0);
return new PrintJob(printJob, this);
} catch (SendIntentException sie) {
Log.e(LOG_TAG, "Couldn't start print job config activity.", sie);
}
} }
} catch (RemoteException re) { } catch (RemoteException re) {
Log.e(LOG_TAG, "Error creating a print job", re); Log.e(LOG_TAG, "Error creating a print job", re);
@ -333,27 +365,6 @@ public final class PrintManager {
return new PrinterDiscoverySession(mService, mContext, mUserId); return new PrinterDiscoverySession(mService, mContext, mUserId);
} }
private static final class PrintClient extends IPrintClient.Stub {
private final WeakReference<PrintManager> mWeakPrintManager;
public PrintClient(PrintManager manager) {
mWeakPrintManager = new WeakReference<PrintManager>(manager);
}
@Override
public void startPrintJobConfigActivity(IntentSender intent) {
PrintManager manager = mWeakPrintManager.get();
if (manager != null) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = manager.mContext;
args.arg2 = intent;
manager.mHandler.obtainMessage(MSG_START_PRINT_JOB_CONFIG_ACTIVITY,
args).sendToTarget();
}
}
}
private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub { private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub {
private final Object mLock = new Object(); private final Object mLock = new Object();

View File

@ -58,8 +58,13 @@
<activity <activity
android:name=".PrintJobConfigActivity" android:name=".PrintJobConfigActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:exported="false" android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE"
android:theme="@style/PrintJobConfigActivityTheme"> android:theme="@style/PrintJobConfigActivityTheme">
<intent-filter>
<action android:name="android.print.PRINT_DILAOG" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="printjob" android:pathPattern="*" />
</intent-filter>
</activity> </activity>
<activity <activity

View File

@ -19,9 +19,11 @@ package com.android.printspooler;
import android.app.Activity; import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
import android.app.LoaderManager; import android.app.LoaderManager;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.Loader; import android.content.Loader;
import android.content.ServiceConnection;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.database.DataSetObserver; import android.database.DataSetObserver;
@ -52,6 +54,7 @@ import android.print.PrintManager;
import android.print.PrinterCapabilitiesInfo; import android.print.PrinterCapabilitiesInfo;
import android.print.PrinterId; import android.print.PrinterId;
import android.print.PrinterInfo; import android.print.PrinterInfo;
import android.provider.DocumentsContract;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter; import android.text.TextUtils.SimpleStringSplitter;
@ -66,9 +69,9 @@ import android.view.View;
import android.view.View.MeasureSpec; import android.view.View.MeasureSpec;
import android.view.View.OnAttachStateChangeListener; import android.view.View.OnAttachStateChangeListener;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewPropertyAnimator; import android.view.ViewPropertyAnimator;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
@ -84,6 +87,8 @@ import android.widget.TextView;
import com.android.printspooler.MediaSizeUtils.MediaSizeComparator; import com.android.printspooler.MediaSizeUtils.MediaSizeComparator;
import libcore.io.IoUtils;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -100,8 +105,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import libcore.io.IoUtils;
/** /**
* Activity for configuring a print job. * Activity for configuring a print job.
*/ */
@ -111,9 +114,6 @@ public class PrintJobConfigActivity extends Activity {
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
public static final String EXTRA_PRINT_DOCUMENT_ADAPTER = "printDocumentAdapter";
public static final String EXTRA_PRINT_JOB = "printJob";
public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID"; public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID";
private static final int LOADER_ID_PRINTERS_LOADER = 1; private static final int LOADER_ID_PRINTERS_LOADER = 1;
@ -177,6 +177,10 @@ public class PrintJobConfigActivity extends Activity {
private Dialog mGeneratingPrintJobDialog; private Dialog mGeneratingPrintJobDialog;
private PrintSpoolerProvider mSpoolerProvider;
private String mCallingPackageName;
@Override @Override
protected void onCreate(Bundle bundle) { protected void onCreate(Bundle bundle) {
super.onCreate(bundle); super.onCreate(bundle);
@ -185,13 +189,13 @@ public class PrintJobConfigActivity extends Activity {
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
PrintJobInfo printJob = extras.getParcelable(EXTRA_PRINT_JOB); PrintJobInfo printJob = extras.getParcelable(PrintManager.EXTRA_PRINT_JOB);
if (printJob == null) { if (printJob == null) {
throw new IllegalArgumentException("printJob cannot be null"); throw new IllegalArgumentException("printJob cannot be null");
} }
mPrintJobId = printJob.getId(); mPrintJobId = printJob.getId();
mIPrintDocumentAdapter = extras.getBinder(EXTRA_PRINT_DOCUMENT_ADAPTER); mIPrintDocumentAdapter = extras.getBinder(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER);
if (mIPrintDocumentAdapter == null) { if (mIPrintDocumentAdapter == null) {
throw new IllegalArgumentException("PrintDocumentAdapter cannot be null"); throw new IllegalArgumentException("PrintDocumentAdapter cannot be null");
} }
@ -201,13 +205,9 @@ public class PrintJobConfigActivity extends Activity {
mCurrPrintAttributes.copyFrom(attributes); mCurrPrintAttributes.copyFrom(attributes);
} }
setContentView(R.layout.print_job_config_activity_container); mCallingPackageName = extras.getString(DocumentsContract.EXTRA_PACKAGE_NAME);
mDocument = new Document(); setContentView(R.layout.print_job_config_activity_container);
mController = new PrintController(new RemotePrintDocumentAdapter(
IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter),
PrintSpoolerService.peekInstance().generateFileForPrintJob(mPrintJobId)));
mEditor = new Editor();
try { try {
mIPrintDocumentAdapter.linkToDeath(mDeathRecipient, 0); mIPrintDocumentAdapter.linkToDeath(mDeathRecipient, 0);
@ -216,14 +216,31 @@ public class PrintJobConfigActivity extends Activity {
return; return;
} }
mController.initialize(); mDocument = new Document();
mEditor.initialize(); mEditor = new Editor();
mSpoolerProvider = new PrintSpoolerProvider(this,
new Runnable() {
@Override
public void run() {
// We got the spooler so unleash the UI.
mController = new PrintController(new RemotePrintDocumentAdapter(
IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter),
mSpoolerProvider.getSpooler().generateFileForPrintJob(mPrintJobId)));
mController.initialize();
mEditor.initialize();
mEditor.postCreate();
}
});
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
mEditor.refreshCurrentPrinter(); if (mSpoolerProvider.getSpooler() != null) {
mEditor.refreshCurrentPrinter();
}
} }
@Override @Override
@ -235,10 +252,10 @@ public class PrintJobConfigActivity extends Activity {
mController.finish(); mController.finish();
} }
if (mEditor.isPrintConfirmed() && mController.isFinished()) { if (mEditor.isPrintConfirmed() && mController.isFinished()) {
PrintSpoolerService.peekInstance().setPrintJobState(mPrintJobId, mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId,
PrintJobInfo.STATE_QUEUED, null); PrintJobInfo.STATE_QUEUED, null);
} else { } else {
PrintSpoolerService.peekInstance().setPrintJobState(mPrintJobId, mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId,
PrintJobInfo.STATE_CANCELED, null); PrintJobInfo.STATE_CANCELED, null);
} }
mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0); mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0);
@ -246,6 +263,7 @@ public class PrintJobConfigActivity extends Activity {
mGeneratingPrintJobDialog.dismiss(); mGeneratingPrintJobDialog.dismiss();
mGeneratingPrintJobDialog = null; mGeneratingPrintJobDialog = null;
} }
mSpoolerProvider.destroy();
super.onDestroy(); super.onDestroy();
} }
@ -367,7 +385,7 @@ public class PrintJobConfigActivity extends Activity {
// we handle writing as usual. // we handle writing as usual.
handleOnLayoutFinished(mDocument.info, false, mRequestCounter.get()); handleOnLayoutFinished(mDocument.info, false, mRequestCounter.get());
} else { } else {
PrintSpoolerService.peekInstance().setPrintJobAttributesNoPersistence( mSpoolerProvider.getSpooler().setPrintJobAttributesNoPersistence(
mPrintJobId, mCurrPrintAttributes); mPrintJobId, mCurrPrintAttributes);
mMetadata.putBoolean(PrintDocumentAdapter.EXTRA_PRINT_PREVIEW, mMetadata.putBoolean(PrintDocumentAdapter.EXTRA_PRINT_PREVIEW,
@ -412,7 +430,7 @@ public class PrintJobConfigActivity extends Activity {
if (infoChanged) { if (infoChanged) {
mDocument.info = info; mDocument.info = info;
// Set the info. // Set the info.
PrintSpoolerService.peekInstance().setPrintJobPrintDocumentInfoNoPersistence( mSpoolerProvider.getSpooler().setPrintJobPrintDocumentInfoNoPersistence(
mPrintJobId, info); mPrintJobId, info);
} }
@ -420,7 +438,7 @@ public class PrintJobConfigActivity extends Activity {
// drop the pages since we have to fetch them again. // drop the pages since we have to fetch them again.
if (infoChanged || layoutChanged) { if (infoChanged || layoutChanged) {
mDocument.pages = null; mDocument.pages = null;
PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence( mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(
mPrintJobId, null); mPrintJobId, null);
} }
@ -499,12 +517,12 @@ public class PrintJobConfigActivity extends Activity {
mControllerState = CONTROLLER_STATE_WRITE_COMPLETED; mControllerState = CONTROLLER_STATE_WRITE_COMPLETED;
// Update the document size. // Update the document size.
File file = PrintSpoolerService.peekInstance() File file = mSpoolerProvider.getSpooler()
.generateFileForPrintJob(mPrintJobId); .generateFileForPrintJob(mPrintJobId);
mDocument.info.setDataSize(file.length()); mDocument.info.setDataSize(file.length());
// Update the print job with the updated info. // Update the print job with the updated info.
PrintSpoolerService.peekInstance().setPrintJobPrintDocumentInfoNoPersistence( mSpoolerProvider.getSpooler().setPrintJobPrintDocumentInfoNoPersistence(
mPrintJobId, mDocument.info); mPrintJobId, mDocument.info);
// Update which pages we have fetched. // Update which pages we have fetched.
@ -528,12 +546,12 @@ public class PrintJobConfigActivity extends Activity {
if (Arrays.equals(writtenPages, requestedPages)) { if (Arrays.equals(writtenPages, requestedPages)) {
// We got a document with exactly the pages we wanted. Hence, // We got a document with exactly the pages we wanted. Hence,
// the printer has to print all pages in the data. // the printer has to print all pages in the data.
PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence(mPrintJobId, mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
ALL_PAGES_ARRAY); ALL_PAGES_ARRAY);
} else if (Arrays.equals(writtenPages, ALL_PAGES_ARRAY)) { } else if (Arrays.equals(writtenPages, ALL_PAGES_ARRAY)) {
// We requested specific pages but got all of them. Hence, // We requested specific pages but got all of them. Hence,
// the printer has to print only the requested pages. // the printer has to print only the requested pages.
PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence(mPrintJobId, mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
requestedPages); requestedPages);
} else if (PageRangeUtils.contains(writtenPages, requestedPages)) { } else if (PageRangeUtils.contains(writtenPages, requestedPages)) {
// We requested specific pages and got more but not all pages. // We requested specific pages and got more but not all pages.
@ -543,7 +561,7 @@ public class PrintJobConfigActivity extends Activity {
final int offset = -writtenPages[0].getStart(); final int offset = -writtenPages[0].getStart();
PageRange[] offsetPages = Arrays.copyOf(requestedPages, requestedPages.length); PageRange[] offsetPages = Arrays.copyOf(requestedPages, requestedPages.length);
PageRangeUtils.offset(offsetPages, offset); PageRangeUtils.offset(offsetPages, offset);
PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence(mPrintJobId, mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
offsetPages); offsetPages);
} else if (Arrays.equals(requestedPages, ALL_PAGES_ARRAY) } else if (Arrays.equals(requestedPages, ALL_PAGES_ARRAY)
&& writtenPages.length == 1 && writtenPages[0].getStart() == 0 && writtenPages.length == 1 && writtenPages[0].getStart() == 0
@ -551,7 +569,7 @@ public class PrintJobConfigActivity extends Activity {
// We requested all pages via the special constant and got all // We requested all pages via the special constant and got all
// of them as an explicit enumeration. Hence, the printer has // of them as an explicit enumeration. Hence, the printer has
// to print only the requested pages. // to print only the requested pages.
PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence(mPrintJobId, mSpoolerProvider.getSpooler().setPrintJobPagesNoPersistence(mPrintJobId,
writtenPages); writtenPages);
} else { } else {
// We did not get the pages we requested, then the application // We did not get the pages we requested, then the application
@ -566,11 +584,12 @@ public class PrintJobConfigActivity extends Activity {
private void requestCreatePdfFileOrFinish() { private void requestCreatePdfFileOrFinish() {
if (mEditor.isPrintingToPdf()) { if (mEditor.isPrintingToPdf()) {
PrintJobInfo printJob = PrintSpoolerService.peekInstance() PrintJobInfo printJob = mSpoolerProvider.getSpooler()
.getPrintJobInfo(mPrintJobId, PrintManager.APP_ID_ANY); .getPrintJobInfo(mPrintJobId, PrintManager.APP_ID_ANY);
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.setType("application/pdf"); intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_TITLE, printJob.getLabel()); intent.putExtra(Intent.EXTRA_TITLE, printJob.getLabel());
intent.putExtra(DocumentsContract.EXTRA_PACKAGE_NAME, mCallingPackageName);
startActivityForResult(intent, ACTIVITY_REQUEST_CREATE_FILE); startActivityForResult(intent, ACTIVITY_REQUEST_CREATE_FILE);
} else { } else {
PrintJobConfigActivity.this.finish(); PrintJobConfigActivity.this.finish();
@ -741,12 +760,12 @@ public class PrintJobConfigActivity extends Activity {
InputStream in = null; InputStream in = null;
OutputStream out = null; OutputStream out = null;
try { try {
PrintJobInfo printJob = PrintSpoolerService.peekInstance() PrintJobInfo printJob = mSpoolerProvider.getSpooler()
.getPrintJobInfo(mPrintJobId, PrintManager.APP_ID_ANY); .getPrintJobInfo(mPrintJobId, PrintManager.APP_ID_ANY);
if (printJob == null) { if (printJob == null) {
return null; return null;
} }
File file = PrintSpoolerService.peekInstance() File file = mSpoolerProvider.getSpooler()
.generateFileForPrintJob(mPrintJobId); .generateFileForPrintJob(mPrintJobId);
in = new FileInputStream(file); in = new FileInputStream(file);
out = getContentResolver().openOutputStream(uri); out = getContentResolver().openOutputStream(uri);
@ -789,21 +808,21 @@ public class PrintJobConfigActivity extends Activity {
private EditText mPageRangeEditText; private EditText mPageRangeEditText;
private Spinner mDestinationSpinner; private Spinner mDestinationSpinner;
private final DestinationAdapter mDestinationSpinnerAdapter; private DestinationAdapter mDestinationSpinnerAdapter;
private Spinner mMediaSizeSpinner; private Spinner mMediaSizeSpinner;
private final ArrayAdapter<SpinnerItem<MediaSize>> mMediaSizeSpinnerAdapter; private ArrayAdapter<SpinnerItem<MediaSize>> mMediaSizeSpinnerAdapter;
private Spinner mColorModeSpinner; private Spinner mColorModeSpinner;
private final ArrayAdapter<SpinnerItem<Integer>> mColorModeSpinnerAdapter; private ArrayAdapter<SpinnerItem<Integer>> mColorModeSpinnerAdapter;
private Spinner mOrientationSpinner; private Spinner mOrientationSpinner;
private final ArrayAdapter<SpinnerItem<Integer>> mOrientationSpinnerAdapter; private ArrayAdapter<SpinnerItem<Integer>> mOrientationSpinnerAdapter;
private Spinner mRangeOptionsSpinner; private Spinner mRangeOptionsSpinner;
private final ArrayAdapter<SpinnerItem<Integer>> mRangeOptionsSpinnerAdapter; private ArrayAdapter<SpinnerItem<Integer>> mRangeOptionsSpinnerAdapter;
private final SimpleStringSplitter mStringCommaSplitter = private SimpleStringSplitter mStringCommaSplitter =
new SimpleStringSplitter(','); new SimpleStringSplitter(',');
private View mContentContainer; private View mContentContainer;
@ -814,7 +833,7 @@ public class PrintJobConfigActivity extends Activity {
private PrinterInfo mCurrentPrinter; private PrinterInfo mCurrentPrinter;
private final MediaSizeComparator mMediaSizeComparator; private MediaSizeComparator mMediaSizeComparator;
private final OnItemSelectedListener mOnItemSelectedListener = private final OnItemSelectedListener mOnItemSelectedListener =
new AdapterView.OnItemSelectedListener() { new AdapterView.OnItemSelectedListener() {
@ -826,6 +845,11 @@ public class PrintJobConfigActivity extends Activity {
return; return;
} }
if (position == AdapterView.INVALID_POSITION) {
updateUi();
return;
}
if (id == DEST_ADAPTER_ITEM_ID_ALL_PRINTERS) { if (id == DEST_ADAPTER_ITEM_ID_ALL_PRINTERS) {
startSelectPrinterActivity(); startSelectPrinterActivity();
return; return;
@ -836,7 +860,7 @@ public class PrintJobConfigActivity extends Activity {
mCurrentPrinter = (PrinterInfo) mDestinationSpinnerAdapter mCurrentPrinter = (PrinterInfo) mDestinationSpinnerAdapter
.getItem(position); .getItem(position);
PrintSpoolerService.peekInstance().setPrintJobPrinterNoPersistence( mSpoolerProvider.getSpooler().setPrintJobPrinterNoPersistence(
mPrintJobId, mCurrentPrinter); mPrintJobId, mCurrentPrinter);
if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) { if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) {
@ -1053,7 +1077,7 @@ public class PrintJobConfigActivity extends Activity {
} }
mCopiesEditText.setError(null); mCopiesEditText.setError(null);
PrintSpoolerService.peekInstance().setPrintJobCopiesNoPersistence( mSpoolerProvider.getSpooler().setPrintJobCopiesNoPersistence(
mPrintJobId, copies); mPrintJobId, copies);
updateUi(); updateUi();
@ -1145,6 +1169,10 @@ public class PrintJobConfigActivity extends Activity {
private boolean mFavoritePrinterSelected; private boolean mFavoritePrinterSelected;
public Editor() { public Editor() {
showUi(UI_EDITING_PRINT_JOB, null);
}
public void postCreate() {
// Destination. // Destination.
mMediaSizeComparator = new MediaSizeComparator(PrintJobConfigActivity.this); mMediaSizeComparator = new MediaSizeComparator(PrintJobConfigActivity.this);
mDestinationSpinnerAdapter = new DestinationAdapter(); mDestinationSpinnerAdapter = new DestinationAdapter();
@ -1621,7 +1649,7 @@ public class PrintJobConfigActivity extends Activity {
if (!TextUtils.equals(mCopiesEditText.getText(), MIN_COPIES_STRING)) { if (!TextUtils.equals(mCopiesEditText.getText(), MIN_COPIES_STRING)) {
mIgnoreNextCopiesChange = true; mIgnoreNextCopiesChange = true;
} }
PrintSpoolerService.peekInstance().setPrintJobCopiesNoPersistence( mSpoolerProvider.getSpooler().setPrintJobCopiesNoPersistence(
mPrintJobId, MIN_COPIES); mPrintJobId, MIN_COPIES);
// Destination. // Destination.
@ -1629,7 +1657,7 @@ public class PrintJobConfigActivity extends Activity {
mDestinationSpinner.setDropDownWidth(ViewGroup.LayoutParams.MATCH_PARENT); mDestinationSpinner.setDropDownWidth(ViewGroup.LayoutParams.MATCH_PARENT);
mDestinationSpinner.setAdapter(mDestinationSpinnerAdapter); mDestinationSpinner.setAdapter(mDestinationSpinnerAdapter);
mDestinationSpinner.setOnItemSelectedListener(mOnItemSelectedListener); mDestinationSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
if (mDestinationSpinnerAdapter.getCount() > 0 && mController.hasStarted()) { if (mDestinationSpinnerAdapter.getCount() > 0) {
mIgnoreNextDestinationChange = true; mIgnoreNextDestinationChange = true;
} }
@ -2089,10 +2117,13 @@ public class PrintJobConfigActivity extends Activity {
@Override @Override
public long getItemId(int position) { public long getItemId(int position) {
if (mPrinters.isEmpty()) { if (mPrinters.isEmpty()) {
if (position == 0 && mFakePdfPrinter != null) { if (position == 0) {
return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF; if (mFakePdfPrinter != null) {
} return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
if (position == 1) { } else {
return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
}
} else if (position == 1) {
return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS; return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
} }
} else { } else {
@ -2484,4 +2515,41 @@ public class PrintJobConfigActivity extends Activity {
} }
} }
} }
private static final class PrintSpoolerProvider implements ServiceConnection {
private final Context mContext;
private final Runnable mCallback;
private PrintSpoolerService mSpooler;
public PrintSpoolerProvider(Context context, Runnable callback) {
mContext = context;
mCallback = callback;
Intent intent = new Intent(mContext, PrintSpoolerService.class);
mContext.bindService(intent, this, 0);
}
public PrintSpoolerService getSpooler() {
return mSpooler;
}
public void destroy() {
if (mSpooler != null) {
mContext.unbindService(this);
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mSpooler = ((PrintSpoolerService.PrintSpooler) service).getService();
if (mSpooler != null) {
mCallback.run();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
/* do noting - we are in the same process */
}
}
} }

View File

@ -16,18 +16,14 @@
package com.android.printspooler; package com.android.printspooler;
import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.content.IntentSender;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
import android.print.IPrintClient;
import android.print.IPrintDocumentAdapter;
import android.print.IPrintSpooler; import android.print.IPrintSpooler;
import android.print.IPrintSpoolerCallbacks; import android.print.IPrintSpoolerCallbacks;
import android.print.IPrintSpoolerClient; import android.print.IPrintSpoolerClient;
@ -50,7 +46,6 @@ import android.util.Slog;
import android.util.Xml; import android.util.Xml;
import com.android.internal.os.HandlerCaller; import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.FastXmlSerializer;
import libcore.io.IoUtils; import libcore.io.IoUtils;
@ -132,110 +127,7 @@ public final class PrintSpoolerService extends Service {
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return new IPrintSpooler.Stub() { return new PrintSpooler();
@Override
public void getPrintJobInfos(IPrintSpoolerCallbacks callback,
ComponentName componentName, int state, int appId, int sequence)
throws RemoteException {
List<PrintJobInfo> printJobs = null;
try {
printJobs = PrintSpoolerService.this.getPrintJobInfos(
componentName, state, appId);
} finally {
callback.onGetPrintJobInfosResult(printJobs, sequence);
}
}
@Override
public void getPrintJobInfo(PrintJobId printJobId, IPrintSpoolerCallbacks callback,
int appId, int sequence) throws RemoteException {
PrintJobInfo printJob = null;
try {
printJob = PrintSpoolerService.this.getPrintJobInfo(printJobId, appId);
} finally {
callback.onGetPrintJobInfoResult(printJob, sequence);
}
}
@SuppressWarnings("deprecation")
@Override
public void createPrintJob(PrintJobInfo printJob, IPrintClient client,
IPrintDocumentAdapter printAdapter) throws RemoteException {
PrintSpoolerService.this.createPrintJob(printJob);
Intent intent = new Intent(printJob.getId().flattenToString());
intent.setClass(PrintSpoolerService.this, PrintJobConfigActivity.class);
intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_DOCUMENT_ADAPTER,
printAdapter.asBinder());
intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_JOB, printJob);
IntentSender sender = PendingIntent.getActivity(
PrintSpoolerService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT
| PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
Message message = mHandlerCaller.obtainMessageO(
HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED,
printJob);
mHandlerCaller.executeOrSendMessage(message);
message = mHandlerCaller.obtainMessageOO(
HandlerCallerCallback.MSG_START_PRINT_JOB_CONFIG_ACTIVITY,
client, sender);
mHandlerCaller.executeOrSendMessage(message);
printJob.setCreationTime(System.currentTimeMillis());
}
@Override
public void setPrintJobState(PrintJobId printJobId, int state, String error,
IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
boolean success = false;
try {
success = PrintSpoolerService.this.setPrintJobState(
printJobId, state, error);
} finally {
callback.onSetPrintJobStateResult(success, sequece);
}
}
@Override
public void setPrintJobTag(PrintJobId printJobId, String tag,
IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
boolean success = false;
try {
success = PrintSpoolerService.this.setPrintJobTag(printJobId, tag);
} finally {
callback.onSetPrintJobTagResult(success, sequece);
}
}
@Override
public void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) {
PrintSpoolerService.this.writePrintJobData(fd, printJobId);
}
@Override
public void setClient(IPrintSpoolerClient client) {
Message message = mHandlerCaller.obtainMessageO(
HandlerCallerCallback.MSG_SET_CLIENT, client);
mHandlerCaller.executeOrSendMessage(message);
}
@Override
public void removeObsoletePrintJobs() {
PrintSpoolerService.this.removeObsoletePrintJobs();
}
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
PrintSpoolerService.this.dump(fd, writer, args);
}
@Override
public void setPrintJobCancelling(PrintJobId printJobId, boolean cancelling) {
PrintSpoolerService.this.setPrintJobCancelling(printJobId, cancelling);
}
};
} }
@Override @Override
@ -286,12 +178,11 @@ public final class PrintSpoolerService extends Service {
private final class HandlerCallerCallback implements HandlerCaller.Callback { private final class HandlerCallerCallback implements HandlerCaller.Callback {
public static final int MSG_SET_CLIENT = 1; public static final int MSG_SET_CLIENT = 1;
public static final int MSG_START_PRINT_JOB_CONFIG_ACTIVITY = 2; public static final int MSG_ON_PRINT_JOB_QUEUED = 2;
public static final int MSG_ON_PRINT_JOB_QUEUED = 3; public static final int MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED = 3;
public static final int MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED = 4; public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 4;
public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 5; public static final int MSG_CHECK_ALL_PRINTJOBS_HANDLED = 5;
public static final int MSG_CHECK_ALL_PRINTJOBS_HANDLED = 6; public static final int MSG_ON_PRINT_JOB_STATE_CHANGED = 6;
public static final int MSG_ON_PRINT_JOB_STATE_CHANGED = 7;
@Override @Override
public void executeMessage(Message message) { public void executeMessage(Message message) {
@ -308,18 +199,6 @@ public final class PrintSpoolerService extends Service {
} }
} break; } break;
case MSG_START_PRINT_JOB_CONFIG_ACTIVITY: {
SomeArgs args = (SomeArgs) message.obj;
IPrintClient client = (IPrintClient) args.arg1;
IntentSender sender = (IntentSender) args.arg2;
args.recycle();
try {
client.startPrintJobConfigActivity(sender);
} catch (RemoteException re) {
Slog.i(LOG_TAG, "Error starting print job config activity!", re);
}
} break;
case MSG_ON_PRINT_JOB_QUEUED: { case MSG_ON_PRINT_JOB_QUEUED: {
PrintJobInfo printJob = (PrintJobInfo) message.obj; PrintJobInfo printJob = (PrintJobInfo) message.obj;
if (mClient != null) { if (mClient != null) {
@ -426,6 +305,11 @@ public final class PrintSpoolerService extends Service {
synchronized (mLock) { synchronized (mLock) {
addPrintJobLocked(printJob); addPrintJobLocked(printJob);
setPrintJobState(printJob.getId(), PrintJobInfo.STATE_CREATED, null); setPrintJobState(printJob.getId(), PrintJobInfo.STATE_CREATED, null);
Message message = mHandlerCaller.obtainMessageO(
HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED,
printJob);
mHandlerCaller.executeOrSendMessage(message);
} }
} }
@ -1277,4 +1161,89 @@ public final class PrintSpoolerService extends Service {
return true; return true;
} }
} }
final class PrintSpooler extends IPrintSpooler.Stub {
@Override
public void getPrintJobInfos(IPrintSpoolerCallbacks callback,
ComponentName componentName, int state, int appId, int sequence)
throws RemoteException {
List<PrintJobInfo> printJobs = null;
try {
printJobs = PrintSpoolerService.this.getPrintJobInfos(
componentName, state, appId);
} finally {
callback.onGetPrintJobInfosResult(printJobs, sequence);
}
}
@Override
public void getPrintJobInfo(PrintJobId printJobId, IPrintSpoolerCallbacks callback,
int appId, int sequence) throws RemoteException {
PrintJobInfo printJob = null;
try {
printJob = PrintSpoolerService.this.getPrintJobInfo(printJobId, appId);
} finally {
callback.onGetPrintJobInfoResult(printJob, sequence);
}
}
@Override
public void createPrintJob(PrintJobInfo printJob) {
PrintSpoolerService.this.createPrintJob(printJob);
}
@Override
public void setPrintJobState(PrintJobId printJobId, int state, String error,
IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
boolean success = false;
try {
success = PrintSpoolerService.this.setPrintJobState(
printJobId, state, error);
} finally {
callback.onSetPrintJobStateResult(success, sequece);
}
}
@Override
public void setPrintJobTag(PrintJobId printJobId, String tag,
IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
boolean success = false;
try {
success = PrintSpoolerService.this.setPrintJobTag(printJobId, tag);
} finally {
callback.onSetPrintJobTagResult(success, sequece);
}
}
@Override
public void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) {
PrintSpoolerService.this.writePrintJobData(fd, printJobId);
}
@Override
public void setClient(IPrintSpoolerClient client) {
Message message = mHandlerCaller.obtainMessageO(
HandlerCallerCallback.MSG_SET_CLIENT, client);
mHandlerCaller.executeOrSendMessage(message);
}
@Override
public void removeObsoletePrintJobs() {
PrintSpoolerService.this.removeObsoletePrintJobs();
}
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
PrintSpoolerService.this.dump(fd, writer, args);
}
@Override
public void setPrintJobCancelling(PrintJobId printJobId, boolean cancelling) {
PrintSpoolerService.this.setPrintJobCancelling(printJobId, cancelling);
}
public PrintSpoolerService getService() {
return PrintSpoolerService.this;
}
}
} }

View File

@ -31,10 +31,10 @@ import android.content.pm.ServiceInfo;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.net.Uri; import android.net.Uri;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle;
import android.os.Process; import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.print.IPrintClient;
import android.print.IPrintDocumentAdapter; import android.print.IPrintDocumentAdapter;
import android.print.IPrintJobStateChangeListener; import android.print.IPrintJobStateChangeListener;
import android.print.IPrintManager; import android.print.IPrintManager;
@ -45,6 +45,7 @@ import android.print.PrintJobInfo;
import android.print.PrinterId; import android.print.PrinterId;
import android.printservice.PrintServiceInfo; import android.printservice.PrintServiceInfo;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import android.util.SparseArray; import android.util.SparseArray;
import com.android.internal.R; import com.android.internal.R;
@ -96,19 +97,19 @@ public final class PrintManagerService extends IPrintManager.Stub {
} }
@Override @Override
public PrintJobInfo print(String printJobName, final IPrintClient client, public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
final IPrintDocumentAdapter documentAdapter, PrintAttributes attributes, PrintAttributes attributes, String packageName, int appId, int userId) {
int appId, int userId) {
final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
String resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName);
final UserState userState; final UserState userState;
synchronized (mLock) { synchronized (mLock) {
userState = getOrCreateUserStateLocked(resolvedUserId); userState = getOrCreateUserStateLocked(resolvedUserId);
} }
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
try { try {
return userState.print(printJobName, client, documentAdapter, return userState.print(printJobName, adapter, attributes,
attributes, resolvedAppId); resolvedPackageName, resolvedAppId);
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
} }
@ -605,6 +606,21 @@ public final class PrintManagerService extends IPrintManager.Stub {
+ "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF."); + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF.");
} }
private String resolveCallingPackageNameEnforcingSecurity(String packageName) {
if (TextUtils.isEmpty(packageName)) {
return null;
}
String[] packages = mContext.getPackageManager().getPackagesForUid(
Binder.getCallingUid());
final int packageCount = packages.length;
for (int i = 0; i < packageCount; i++) {
if (packageName.equals(packages[i])) {
return packageName;
}
}
return null;
}
private void showEnableInstalledPrintServiceNotification(ComponentName component, private void showEnableInstalledPrintServiceNotification(ComponentName component,
String label) { String label) {
Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS); Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS);

View File

@ -26,8 +26,6 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle; import android.os.UserHandle;
import android.print.IPrintClient;
import android.print.IPrintDocumentAdapter;
import android.print.IPrintSpooler; import android.print.IPrintSpooler;
import android.print.IPrintSpoolerCallbacks; import android.print.IPrintSpoolerCallbacks;
import android.print.IPrintSpoolerClient; import android.print.IPrintSpoolerClient;
@ -130,15 +128,14 @@ final class RemotePrintSpooler {
return null; return null;
} }
public final void createPrintJob(PrintJobInfo printJob, IPrintClient client, public final void createPrintJob(PrintJobInfo printJob) {
IPrintDocumentAdapter documentAdapter) {
throwIfCalledOnMainThread(); throwIfCalledOnMainThread();
synchronized (mLock) { synchronized (mLock) {
throwIfDestroyedLocked(); throwIfDestroyedLocked();
mCanUnbind = false; mCanUnbind = false;
} }
try { try {
getRemoteInstanceLazy().createPrintJob(printJob, client, documentAdapter); getRemoteInstanceLazy().createPrintJob(printJob);
} catch (RemoteException re) { } catch (RemoteException re) {
Slog.e(LOG_TAG, "Error creating print job.", re); Slog.e(LOG_TAG, "Error creating print job.", re);
} catch (TimeoutException te) { } catch (TimeoutException te) {

View File

@ -16,16 +16,20 @@
package com.android.server.print; package com.android.server.print;
import android.app.PendingIntent;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice; import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.IBinder.DeathRecipient; import android.os.IBinder.DeathRecipient;
@ -33,7 +37,6 @@ import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.RemoteCallbackList; import android.os.RemoteCallbackList;
import android.os.RemoteException; import android.os.RemoteException;
import android.print.IPrintClient;
import android.print.IPrintDocumentAdapter; import android.print.IPrintDocumentAdapter;
import android.print.IPrintJobStateChangeListener; import android.print.IPrintJobStateChangeListener;
import android.print.IPrinterDiscoveryObserver; import android.print.IPrinterDiscoveryObserver;
@ -44,6 +47,7 @@ import android.print.PrintManager;
import android.print.PrinterId; import android.print.PrinterId;
import android.print.PrinterInfo; import android.print.PrinterInfo;
import android.printservice.PrintServiceInfo; import android.printservice.PrintServiceInfo;
import android.provider.DocumentsContract;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter; import android.text.TextUtils.SimpleStringSplitter;
@ -158,9 +162,9 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
mSpooler.removeObsoletePrintJobs(); mSpooler.removeObsoletePrintJobs();
} }
public PrintJobInfo print(String printJobName, final IPrintClient client, @SuppressWarnings("deprecation")
final IPrintDocumentAdapter documentAdapter, PrintAttributes attributes, public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
int appId) { PrintAttributes attributes, String packageName, int appId) {
// Create print job place holder. // Create print job place holder.
final PrintJobInfo printJob = new PrintJobInfo(); final PrintJobInfo printJob = new PrintJobInfo();
printJob.setId(new PrintJobId()); printJob.setId(new PrintJobId());
@ -169,9 +173,10 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
printJob.setAttributes(attributes); printJob.setAttributes(attributes);
printJob.setState(PrintJobInfo.STATE_CREATED); printJob.setState(PrintJobInfo.STATE_CREATED);
printJob.setCopies(1); printJob.setCopies(1);
printJob.setCreationTime(System.currentTimeMillis());
// Track this job so we can forget it when the creator dies. // Track this job so we can forget it when the creator dies.
if (!mPrintJobForAppCache.onPrintJobCreated(client.asBinder(), appId, if (!mPrintJobForAppCache.onPrintJobCreated(adapter.asBinder(), appId,
printJob)) { printJob)) {
// Not adding a print job means the client is dead - done. // Not adding a print job means the client is dead - done.
return null; return null;
@ -181,12 +186,31 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
new AsyncTask<Void, Void, Void>() { new AsyncTask<Void, Void, Void>() {
@Override @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) {
mSpooler.createPrintJob(printJob, client, documentAdapter); mSpooler.createPrintJob(printJob);
return null; return null;
} }
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
return printJob; final long identity = Binder.clearCallingIdentity();
try {
Intent intent = new Intent(PrintManager.ACTION_PRINT_DIALOG);
intent.setData(Uri.fromParts("printjob", printJob.getId().flattenToString(), null));
intent.putExtra(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER, adapter.asBinder());
intent.putExtra(PrintManager.EXTRA_PRINT_JOB, printJob);
intent.putExtra(DocumentsContract.EXTRA_PACKAGE_NAME, packageName);
IntentSender intentSender = PendingIntent.getActivity(
mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT
| PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
Bundle result = new Bundle();
result.putParcelable(PrintManager.EXTRA_PRINT_JOB, printJob);
result.putParcelable(PrintManager.EXTRA_PRINT_DIALOG_INTENT, intentSender);
return result;
} finally {
Binder.restoreCallingIdentity(identity);
}
} }
public List<PrintJobInfo> getPrintJobInfos(int appId) { public List<PrintJobInfo> getPrintJobInfos(int appId) {