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. We used to show a single notificaiton for every print job but
this is against th UX guidelines. Since we have to lead by
example, this change adds coalescing of multiple notifications.
bug:11155212
2. Print job state callback in the PrintManager now correctly
invoked on the main thread.
bug:10983508
Change-Id: I906e9e62198fa37cb4d2f71fce07ed475d61e1bd
1. We want the files for a print job to be removed as early as possible
typically because the print job was cancelled, completed, the app
or the spooler crashed during print job construction. We were keeping
around in the spooler and hence to disc infos for jobs that are in
final state since the app that created them may hold a reference to
a local print job objec whose info it can access to get the latest
print job state potentially after the job reached final state. The
issue was that we were persisting to disc created print jobs which
were during construction which requires careful handling for the
various cases above. This is tricky and error prone.
We used to tell the spooler to forget the print jobs infos when the
app that created them died. The implementation to forget a print
job was not careful and was nuking currently running print jobs in
addition to the ones in a terminal state. Further, if the app dies
before a print job is completed we were left with a stale print
job in the spooler since we missed the signal to forget it (assuming
we forget only inactive jobs). These issues suggest that the approach
is problematic.
Now we have a cache of print job infos for the jobs an app created.
This cache is updated when the state of a print jobs changes using
the new print job state observation code. When the app dies we
remove the cached jobs for that app. Now if the app calls to get
the print jobs it gets the cached ones, i.e. the print jobs it
created during its lifetime, plus the print jobs that are still
active fetched from the spooler. Note that transient state cannot
be kept in the spooler since we unbind from it if there is no
work and it may get killed.
2. Improved the print sub-system logging code to show the cached
print job infos for apps and also dump the print job PDF file
names.
bug:10958357
Change-Id: I6f7c1968b6b7ba5be182a10df044ff7ea1fc3a61
1. The UI of a printing app was freezing a little when calling the print
method since the print manager service was waiting for it to bind to the
print spooler which generated the print job id (and the initial print
job info really). Now the print manager service is responsible for job
id generation and does not not wait for the print spooler to spin. Hence,
the app UI is not blocked at all. Note that the print manager initiates
the binding to the spooler and as soon as it completes the spooler shows
the print UI which is hosted in its process. It is not possible to show
the print UI before the system is bound to the spooler since during this
binding the system passes a callback to the spooler so the latter can
talk to the system.
2. Changed the print job id to be an opaque class allowing us to vary the
way we generate print job ids in the future.
3. The queued print job state was hidden but the print job returned by the
print method of the print manager is in that state. Now now hidden.
4. We were incorrecly removing print job infos if they are completed or
cancelled. Doing that is problematic since the print job returned by
the print method allows the app to query for the job info after the
job has been say completed. Hence, an app can initiate printing and
get a print job whose state is "created" and hold onto it until after
the job is completed, now if the app asks for the print job info it
will get an info in "created" state even though the job is "completed"
since the spooler was not retaining the completed jobs. Now the spooler
removes the PDF files for the completed and cancelled print jobs but
keeps around the infos (also persisting them to disc) so it can answer
questions about them. On first boot or switch to a user we purge the
persisted print jobs in completed/cancelled state since they
are obsolete - no app can have a handle to them.
5. Removed the print method that takes a file since we have a public
PrintDocumentAdapter implementation for printing files. Once can
instantiate a PrintFileDocumentAdapter and pass it to the print
method. This class also allows overriding of the finish method to
know when the data is spooled and deleted the file if desired, etc.
6. Replaced the wrong code to slice a large list of parcelables to
use ParceledListSlice class.
bug:10748093
Change-Id: I1ebeeb47576e88fce550851cdd3e401fcede6e2b
1. Now after a print service crashes we are bringing it to the same
state of its lifecycle. For example, if a service does a discovery
and crashes we recreate the discovery session call the start
discovery method and so on.
2. Turned off debugging logs since we have fully fledged state dump.
bug:10697779
Change-Id: Id790537461428e96b197eef12258996bda2bd1ce
Being able to dump the state of the print sub-system especially when
taking a bugreport is very useful for bug fixing and observing whether
the print system operates properly.
bug:10659019
Change-Id: Id098b788f474ab17766966a4563ffdfc0171c76b
1. Added support for selecting a printer from the all printers activity
that is not in the initial printer selection drop down. The user
initially sees a sub set of the printers in the drop down and the
last option is to see all printers in a separate activity. Some
of the printers in the all printers activity are not shown in the
initial drop down.
2. Refactored printer discovery by adding (private for now) printer
discovery app facing APIs. These APIs are needed to support multiple
printer selection activities (print dialog and all printers activities)
and also the settings for showing all printers for a service.
Now multiple apps can request observing for printers and there is
a centralized mediator that ensures the same printer discovery
session is used. The mediator dispatches printer discovery specific
requests to print services. It also aggregates discovered printers
and delivers them to the interested apps. The mediator minimizes
printer discovery session creation and starting and stopping discovery
by sharing the same discovery session and discovery window with
multiple apps. Lastly, the mediator takes care of print services
enabled during discovery by bringing them up to the current
discovery state (create discovery session and start discovery if
needed). The mediator also reports disappearing of the printers
of a service removed during discovery and notifies a newly
registered observers for the currnet printers if the observers are
added during an active printer discovery session.
3. Fixed bugs in the print UI and implemented some UX tweaks.
Change-Id: I4d0b0c5a6c6f1809b2ba5dbc8e9d63ab3d48f1ef
1. Added past printer history tracking and merging favorite printers
with discovered printers.
2. Added save as PDF support.
3. Added all printers activity with search capability and optional
add printers chooser (if any print service provides add printers
activity)
4. Refactored the printer discovery session APIs. Now one session
can have multiple window discovery windows and the session stores
the printers found during past discovery periods.
5. Merged the print spooler and the print spooler service - much
simpler and easier to maintain.
Change-Id: I4830b0eb6367e1c748b768a5ea9ea11baf36cfad
1. Factored out the printer discovery APIs of a print service in a
dedicated session object that is created by the print service on
demand. This ensures that added/removed/updated printers from
one session do not interfere with another session.
2. Updated the app facing APIs to pass in a document info along
with a printed file. Also exposed the print file adapter so
apps that create a temporary file for printing can intercept
when it is read by the system so the file can be deleted.
3. Updated the print service documentation.
Change-Id: I3473d586c26d8bda1cf7e2bdacb441aa9df982ed
1. The singleton print spooler isntance is created when the print spooler
service gets a connection to the system and is destroyed when this
connection is removed. Note that if the spooler has work, then the
connection to the system will not be removed.
When the spooler is created, it reads the stored state and notifies the
system which in turn dispatches this to the print services.
When the system connects to the spooler and passes it a connection, we
schedule a delayed check whether there is work for the spooler. We do
not handle this immediately to avoid intermitted spinning on and off
of the spooler process if a client makes a sequence of queries while
the spooler has really no work.
2. Fixed a bug in the NotificationManagerService where adding a notification
and removing it immediately after that does not remove the notification.
The code that is adding a notification is run on a handler thread while
the code to remove it on the calling thread. This creates a race and
erroneous results. Now the removal is also scheduled on the handler.
3. Many small fixes here and there.
Change-Id: I6415c253139fa6616393fbe23c659d031a29e1f6
1. Added notifications for a queued print job, for a started print job,
for ongoing canceling a print job, and for a failed print job. The
notifications for queued and started state have a cancel action. The
notification for failed print job has a cancel and a restart action.
2. Propagating failure message from the print service to the notifications.
3. PrintJobConfigActivity was not setting the initial value for the
print job copies and was not updating the UI immediately after creation.
4. Refactored PrintJobConfigActivity to avoid using the hack to avoid
reaction for item selection change in a spinner for an event that
happened before the callback was registered.
5. Removed the label attribute from PrinterInfo and now PrinterId is
composed of the printer name and the service component name. This
is nice since for restarting print jobs we do not need to store
information about the printer except the printer id which is
already part of the PrintJobInfo's data. Also the printer name
is not expected to change anyway.
6. Allowing cancellation of a queued print job. Also no print job is
cancelled without asking the managing print service to do that.
Before we were immediately canceling print jobs in queued state
but it was possible for a buggy print service to not set the
print job state to started before starting to do expensive work
that will not be canceled.
7. PrintServiceInfo was throwing an exception the the meta-data
XML for the print service was not well-formed which would crash
the system process. Now we just ignore not well-formed meta-data.
8. Removed unused permissions from the PrintSpooler's manifest.
Change-Id: Iba2dd14b487f56e137b90d1da17c3033422ab5e6
1. Added APIs for adding partially initialized PrintInfo objects
enabling light-weight lookps for print serivces that want to
populate the list of available printers without querying each
of them for its capabilities. This includes APIs for the system
to request from a print service to update certain printers.
2. Fixed a bug in PrinterId#equals().
3. Added equals and hasCode implementaion to PrinterInfo. Also
the defaul in PrinterInfo are now an array instead of a
SparseArray - cheaper.
4. Now PrintJobConfigActivity works with partially specified
printers. Specifically, if such a printer is selected the
activity is requesting from the print service to update
the printer. We are currently not handling the timeout case.
It also handles udpated pritners.
Change-Id: I5e83e924ef597c9e22cbd06a971d4f4d3bd3a9c1
1. API changes: Moved copies API from PrintAttributes to PrintJobInfo;
Changed the PageRange list to an array in PrintDocumentAdapter#onWrite;
Added onCancelled method to the layout and write callbacks.
2. Refactored the serialization of remote layout and write commands. Now
the commands are serialized by the code in the client instead in the spooler.
The benefit is simple code since the client has to do a serialization to delegate
to the main thread anyway. The increased IPC found is fine since these calls
are quite unfrequent.
3. Removed an unused file: IPrintSpoolerObserver.aidl
4. Added equals and hasCode implementation to PageRange, PrintAttributes,
MediaSize, Resolution, Margins, Tray, PrintDocumentInfo.
5. Added shortcut path for query APIs on PrintJob that return cached values
if the print job is in a uncuttable state, i.e. completed or cancelled. Failed
print jobs can be restarted.
6. PrintJobInfo was not properly serialized.
7. Updated the look of the print dialog to be stable if there is and there isn't
currently selected printer.
8. PrintJobCOnfigActivity now calls onLayout on every print attributes change
but requests a write only on print preview or print button press. Also if the
layout did not change the content and it is already written no subsequent
call is made. Also if the selected pages change and we already have them
no subsequent call to write is made. Also the app is called with print preview
attribute set when performing layout and with it cleared after the print button
is pressed. A lot of changes making sure that only valid actions are enabled
in the activity (looks like a dialog) at a given time frame. The print job config
activity is also hidden after we got all the data, i.e. layout and write are done.
9. The callback from the print spooler to the system are scheduled via messages
to avoid lock being held during the call. It was hard to guarantee that since a
method holding a lock may be calling one that would like to release the lock
at some point to make the callbacks.
10. Print spooler state is persisted only if something changes in a completed
print job, i.e. not one that is being constructed due the print job config dialog.
11. Fixed a potential race in the RemotePrintSpooler where it was possible that
a client that got a handle to the remote spooler calls into an unbound spooler.
E.g: the client gets the remote interface with a lock held, now the client releases
the lock to avoid IPC with a lock, during the IPC scheduling the spooler has
notified the system that it is done and the system unbinds from it, now the
client's IPC is made to a spooler that is disconnected.
Change-Id: Ie9c42255940a27ecaed21a4d326a663a4788ac9d
1. Now a user state has ins own spooler since the spooler app is
running per user. The user state registers an observer for the state
of the spooler to get information needed to orchestrate unbinding
from print serivces that have no work and eventually unbinding from
the spooler when all no service has any work.
2. Abstracted a remote print service from the perspective of the system
in a class that is transparently managing binding and unbinding to
the remote instance.
3. Abstracted the remote print spooler to transparently manage binding
and unbinding to the remote instance when there is work and when
there is no work, respectively.
4. Cleaned up the print document adapter (ex-PrintAdapter) APIs to
enable implementing the all callbacks on a thread of choice. If
the document is really small, using the main thread makes sense.
Now if an app that does not need the UI state to layout the printed
content, it can schedule all the work for allocating resources, laying
out, writing, and releasing resources on a dedicated thread.
5. Added info class for the printed document that is now propagated
the the print services. A print service gets an instance of a
new document class that encapsulates the document info and a method
to access the document's data.
6. Added APIs for describing the type of a document to the new document
info class. This allows a print service to do smarts based on the
doc type. For now we have only photo and document types.
7. Renamed the systemReady method for system services that implement
it with different semantics to systemRunning. Such methods assume
the the service can run third-party code which is not the same as
systemReady.
8. Cleaned up the print job configuration activity.
9. Sigh... code clean up here and there. Factoring out classes to
improve readability.
Change-Id: I637ba28412793166cbf519273fdf022241159a92