Skip to content

Commit 7bfbbcb

Browse files
committed
Refactor how the print dialog activity is started.
1. Before the print job activity was started asyncronously with respect to the print call on to the print manager. This was creating a situation where the starting activity may finish before the print dialog appears which may lead to an orphaned print document adapter with no data to print (as the UI is is gone), or strange behaviors where the print dialog starts on as a separate task. To address this the pending intent for starting the print dialog is not started by the print spooler since we cannot call into it synchronously as we have to start its process and bind to the spooler service which leads to jankyness in the client app. Now the pending intent is created by the print manager service in the synchronous print call so from an app's perspective calling print starts the activity. The side effect of this design is that the print dialog activity may start before the system is bound to the spooler service. In such a case the print activity cannot start poking the print spooler state as the system registers callback to observe the spooler state. To address this the print spooler activity disables the UI and also binds to the spooler service which happenes immediately after it is started. As soon as the print dialog binds to the service it starts the UI. 2. Fixed an bug in the printer adapter of the print dialog that was leading to a crash if the only item in the adater is the all pritners option and it is selected. 3. Piping the package name that started the printing so we can pass it to the storage UI as a hint to open the last location the app used. bug:11127269 Change-Id: Ia93820bdae0b0e7600a0930b1f10d9708bd86b68
1 parent 1db8cf1 commit 7bfbbcb

File tree

11 files changed

+333
-246
lines changed

11 files changed

+333
-246
lines changed

Android.mk

-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ LOCAL_SRC_FILES += \
165165
core/java/android/print/ILayoutResultCallback.aidl \
166166
core/java/android/print/IPrinterDiscoveryObserver.aidl \
167167
core/java/android/print/IPrintDocumentAdapter.aidl \
168-
core/java/android/print/IPrintClient.aidl \
169168
core/java/android/print/IPrintJobStateChangeListener.aidl \
170169
core/java/android/print/IPrintManager.aidl \
171170
core/java/android/print/IPrintSpooler.aidl \

CleanSpec.mk

+2
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ $(call add-clean-step, rm -f $(PRODUCT_OUT)/system/media/video/*)
183183
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
184184
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/effects/)
185185
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/framework-res_intermediates)
186+
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrintClient.*)
187+
186188
# ************************************************
187189
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
188190
# ************************************************

core/java/android/print/IPrintManager.aidl

+3-4
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616

1717
package android.print;
1818

19+
import android.os.Bundle;
1920
import android.print.IPrinterDiscoveryObserver;
2021
import android.print.IPrintDocumentAdapter;
21-
import android.print.IPrintClient;
2222
import android.print.PrintJobId;
2323
import android.print.IPrintJobStateChangeListener;
2424
import android.print.PrinterId;
@@ -34,9 +34,8 @@ import android.printservice.PrintServiceInfo;
3434
interface IPrintManager {
3535
List<PrintJobInfo> getPrintJobInfos(int appId, int userId);
3636
PrintJobInfo getPrintJobInfo(in PrintJobId printJobId, int appId, int userId);
37-
PrintJobInfo print(String printJobName, in IPrintClient client,
38-
in IPrintDocumentAdapter printAdapter, in PrintAttributes attributes,
39-
int appId, int userId);
37+
Bundle print(String printJobName, in IPrintDocumentAdapter printAdapter,
38+
in PrintAttributes attributes, String packageName, int appId, int userId);
4039
void cancelPrintJob(in PrintJobId printJobId, int appId, int userId);
4140
void restartPrintJob(in PrintJobId printJobId, int appId, int userId);
4241

core/java/android/print/IPrintSpooler.aidl

+1-4
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ package android.print;
1818

1919
import android.content.ComponentName;
2020
import android.os.ParcelFileDescriptor;
21-
import android.print.IPrintDocumentAdapter;
22-
import android.print.IPrintClient;
2321
import android.print.IPrintSpoolerClient;
2422
import android.print.IPrintSpoolerCallbacks;
2523
import android.print.PrinterInfo;
@@ -40,8 +38,7 @@ oneway interface IPrintSpooler {
4038
int state, int appId, int sequence);
4139
void getPrintJobInfo(in PrintJobId printJobId, IPrintSpoolerCallbacks callback,
4240
int appId, int sequence);
43-
void createPrintJob(in PrintJobInfo printJob, in IPrintClient client,
44-
in IPrintDocumentAdapter printAdapter);
41+
void createPrintJob(in PrintJobInfo printJob);
4542
void setPrintJobState(in PrintJobId printJobId, int status, String stateReason,
4643
IPrintSpoolerCallbacks callback, int sequence);
4744
void setPrintJobTag(in PrintJobId printJobId, String tag, IPrintSpoolerCallbacks callback,

core/java/android/print/PrintManager.java

+56-45
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,47 @@ public final class PrintManager {
6060

6161
private static final boolean DEBUG = false;
6262

63-
private static final int MSG_START_PRINT_JOB_CONFIG_ACTIVITY = 1;
64-
private static final int MSG_NOTIFY_PRINT_JOB_STATE_CHANGED = 2;
63+
private static final int MSG_NOTIFY_PRINT_JOB_STATE_CHANGED = 1;
64+
65+
/**
66+
* The action for launching the print dialog activity.
67+
*
68+
* @hide
69+
*/
70+
public static final String ACTION_PRINT_DIALOG = "android.print.PRINT_DIALOG";
71+
72+
/**
73+
* Extra with the intent for starting the print dialog.
74+
* <p>
75+
* <strong>Type:</strong> {@link android.content.IntentSender}
76+
* </p>
77+
*
78+
* @hide
79+
*/
80+
public static final String EXTRA_PRINT_DIALOG_INTENT =
81+
"android.print.intent.extra.EXTRA_PRINT_DIALOG_INTENT";
82+
83+
/**
84+
* Extra with a print job.
85+
* <p>
86+
* <strong>Type:</strong> {@link android.print.PrintJobInfo}
87+
* </p>
88+
*
89+
* @hide
90+
*/
91+
public static final String EXTRA_PRINT_JOB =
92+
"android.print.intent.extra.EXTRA_PRINT_JOB";
93+
94+
/**
95+
* Extra with the print document adapter to be printed.
96+
* <p>
97+
* <strong>Type:</strong> {@link android.print.IPrintDocumentAdapter}
98+
* </p>
99+
*
100+
* @hide
101+
*/
102+
public static final String EXTRA_PRINT_DOCUMENT_ADAPTER =
103+
"android.print.intent.extra.EXTRA_PRINT_DOCUMENT_ADAPTER";
65104

66105
/** @hide */
67106
public static final int APP_ID_ANY = -2;
@@ -74,8 +113,6 @@ public final class PrintManager {
74113

75114
private final int mAppId;
76115

77-
private final PrintClient mPrintClient;
78-
79116
private final Handler mHandler;
80117

81118
private Map<PrintJobStateChangeListener, PrintJobStateChangeListenerWrapper> mPrintJobStateChangeListeners;
@@ -103,33 +140,18 @@ public PrintManager(Context context, IPrintManager service, int userId, int appI
103140
mService = service;
104141
mUserId = userId;
105142
mAppId = appId;
106-
mPrintClient = new PrintClient(this);
107143
mHandler = new Handler(context.getMainLooper(), null, false) {
108144
@Override
109145
public void handleMessage(Message message) {
110146
switch (message.what) {
111-
case MSG_START_PRINT_JOB_CONFIG_ACTIVITY: {
112-
SomeArgs args = (SomeArgs) message.obj;
113-
Context context = (Context) args.arg1;
114-
IntentSender intent = (IntentSender) args.arg2;
115-
args.recycle();
116-
try {
117-
context.startIntentSender(intent, null, 0, 0, 0);
118-
} catch (SendIntentException sie) {
119-
Log.e(LOG_TAG, "Couldn't start print job config activity.", sie);
120-
}
121-
}
122-
break;
123-
124147
case MSG_NOTIFY_PRINT_JOB_STATE_CHANGED: {
125148
SomeArgs args = (SomeArgs) message.obj;
126149
PrintJobStateChangeListener listener =
127150
(PrintJobStateChangeListener) args.arg1;
128151
PrintJobId printJobId = (PrintJobId) args.arg2;
129152
args.recycle();
130153
listener.onPrintJobStateChanged(printJobId);
131-
}
132-
break;
154+
} break;
133155
}
134156
}
135157
};
@@ -279,10 +301,20 @@ public PrintJob print(String printJobName, PrintDocumentAdapter documentAdapter,
279301
PrintDocumentAdapterDelegate delegate = new PrintDocumentAdapterDelegate(documentAdapter,
280302
mContext.getMainLooper());
281303
try {
282-
PrintJobInfo printJob = mService.print(printJobName, mPrintClient, delegate,
283-
attributes, mAppId, mUserId);
284-
if (printJob != null) {
285-
return new PrintJob(printJob, this);
304+
Bundle result = mService.print(printJobName, delegate,
305+
attributes, mContext.getPackageName(), mAppId, mUserId);
306+
if (result != null) {
307+
PrintJobInfo printJob = result.getParcelable(EXTRA_PRINT_JOB);
308+
IntentSender intent = result.getParcelable(EXTRA_PRINT_DIALOG_INTENT);
309+
if (printJob == null || intent == null) {
310+
return null;
311+
}
312+
try {
313+
mContext.startIntentSender(intent, null, 0, 0, 0);
314+
return new PrintJob(printJob, this);
315+
} catch (SendIntentException sie) {
316+
Log.e(LOG_TAG, "Couldn't start print job config activity.", sie);
317+
}
286318
}
287319
} catch (RemoteException re) {
288320
Log.e(LOG_TAG, "Error creating a print job", re);
@@ -333,27 +365,6 @@ public PrinterDiscoverySession createPrinterDiscoverySession() {
333365
return new PrinterDiscoverySession(mService, mContext, mUserId);
334366
}
335367

336-
private static final class PrintClient extends IPrintClient.Stub {
337-
338-
private final WeakReference<PrintManager> mWeakPrintManager;
339-
340-
public PrintClient(PrintManager manager) {
341-
mWeakPrintManager = new WeakReference<PrintManager>(manager);
342-
}
343-
344-
@Override
345-
public void startPrintJobConfigActivity(IntentSender intent) {
346-
PrintManager manager = mWeakPrintManager.get();
347-
if (manager != null) {
348-
SomeArgs args = SomeArgs.obtain();
349-
args.arg1 = manager.mContext;
350-
args.arg2 = intent;
351-
manager.mHandler.obtainMessage(MSG_START_PRINT_JOB_CONFIG_ACTIVITY,
352-
args).sendToTarget();
353-
}
354-
}
355-
}
356-
357368
private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub {
358369

359370
private final Object mLock = new Object();

packages/PrintSpooler/AndroidManifest.xml

+6-1
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,13 @@
5858
<activity
5959
android:name=".PrintJobConfigActivity"
6060
android:configChanges="orientation|screenSize"
61-
android:exported="false"
61+
android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE"
6262
android:theme="@style/PrintJobConfigActivityTheme">
63+
<intent-filter>
64+
<action android:name="android.print.PRINT_DILAOG" />
65+
<category android:name="android.intent.category.DEFAULT" />
66+
<data android:scheme="printjob" android:pathPattern="*" />
67+
</intent-filter>
6368
</activity>
6469

6570
<activity

0 commit comments

Comments
 (0)