Merge "Print UI bug fixing and printer discovery refactoring." into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
826debf5f8
@@ -162,6 +162,7 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/os/IVibratorService.aidl \
|
||||
core/java/android/service/notification/INotificationListener.aidl \
|
||||
core/java/android/print/ILayoutResultCallback.aidl \
|
||||
core/java/android/print/IPrinterDiscoveryObserver.aidl \
|
||||
core/java/android/print/IPrintDocumentAdapter.aidl \
|
||||
core/java/android/print/IPrintClient.aidl \
|
||||
core/java/android/print/IPrintManager.aidl \
|
||||
|
||||
@@ -18,8 +18,6 @@ package android.os;
|
||||
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Takes care of the grunt work of maintaining a list of remote interfaces,
|
||||
* typically for the use of performing callbacks from a
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package android.print;
|
||||
|
||||
import android.print.IPrinterDiscoveryObserver;
|
||||
import android.print.IPrintDocumentAdapter;
|
||||
import android.print.IPrintClient;
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintAttributes;
|
||||
|
||||
@@ -34,4 +36,12 @@ interface IPrintManager {
|
||||
int appId, int userId);
|
||||
void cancelPrintJob(int printJobId, int appId, int userId);
|
||||
void restartPrintJob(int printJobId, int appId, int userId);
|
||||
|
||||
void createPrinterDiscoverySession(in IPrinterDiscoveryObserver observer, int userId);
|
||||
void startPrinterDiscovery(in IPrinterDiscoveryObserver observer,
|
||||
in List<PrinterId> priorityList, int userId);
|
||||
void stopPrinterDiscovery(in IPrinterDiscoveryObserver observer, int userId);
|
||||
void requestPrinterUpdate(in PrinterId printerId, int userId);
|
||||
void destroyPrinterDiscoverySession(in IPrinterDiscoveryObserver observer,
|
||||
int userId);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package android.print;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.print.PrinterId;
|
||||
import android.print.IPrintDocumentAdapter;
|
||||
import android.print.IPrintClient;
|
||||
import android.print.IPrintSpoolerClient;
|
||||
@@ -47,9 +46,4 @@ oneway interface IPrintSpooler {
|
||||
int sequence);
|
||||
void writePrintJobData(in ParcelFileDescriptor fd, int printJobId);
|
||||
void setClient(IPrintSpoolerClient client);
|
||||
|
||||
// Printer discovery APIs
|
||||
void onPrintersAdded(in List<PrinterInfo> printers);
|
||||
void onPrintersRemoved(in List<PrinterId> printerIds);
|
||||
void onPrintersUpdated(in List<PrinterInfo> printerIds);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package android.print;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrintJobInfo;
|
||||
|
||||
|
||||
@@ -30,11 +29,4 @@ oneway interface IPrintSpoolerClient {
|
||||
void onPrintJobQueued(in PrintJobInfo printJob);
|
||||
void onAllPrintJobsForServiceHandled(in ComponentName printService);
|
||||
void onAllPrintJobsHandled();
|
||||
|
||||
// Printer discovery APIs
|
||||
void createPrinterDiscoverySession();
|
||||
void startPrinterDiscovery(in List<PrinterId> priorityList);
|
||||
void stopPrinterDiscovery();
|
||||
void requestPrinterUpdate(in PrinterId printerId);
|
||||
void destroyPrinterDiscoverySession();
|
||||
}
|
||||
|
||||
32
core/java/android/print/IPrinterDiscoveryObserver.aidl
Normal file
32
core/java/android/print/IPrinterDiscoveryObserver.aidl
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 android.print;
|
||||
|
||||
import android.print.IPrintClient;
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrinterInfo;
|
||||
|
||||
/**
|
||||
* Interface for observing discovered printers by a discovery session.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IPrinterDiscoveryObserver {
|
||||
void onPrintersAdded(in List<PrinterInfo> printers);
|
||||
void onPrintersRemoved(in List<PrinterId> printerIds);
|
||||
void onPrintersUpdated(in List<PrinterInfo> printerIds);
|
||||
}
|
||||
@@ -204,6 +204,13 @@ public final class PrintManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public PrinterDiscoverySession createPrinterDiscoverySession() {
|
||||
return new PrinterDiscoverySession(mService, mContext, mUserId);
|
||||
}
|
||||
|
||||
private static final class PrintClient extends IPrintClient.Stub {
|
||||
|
||||
private final WeakReference<PrintManager> mWeakPrintManager;
|
||||
|
||||
297
core/java/android/print/PrinterDiscoverySession.java
Normal file
297
core/java/android/print/PrinterDiscoverySession.java
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* 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 android.print;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public final class PrinterDiscoverySession {
|
||||
|
||||
private static final String LOG_TAG ="PrinterDiscoverySession";
|
||||
|
||||
private static final int MSG_PRINTERS_ADDED = 1;
|
||||
private static final int MSG_PRINTERS_REMOVED = 2;
|
||||
private static final int MSG_PRINTERS_UPDATED = 3;
|
||||
|
||||
private final ArrayMap<PrinterId, PrinterInfo> mPrinters =
|
||||
new ArrayMap<PrinterId, PrinterInfo>();
|
||||
|
||||
private final IPrintManager mPrintManager;
|
||||
|
||||
private final int mUserId;
|
||||
|
||||
private final Handler mHandler;
|
||||
|
||||
private IPrinterDiscoveryObserver mObserver;
|
||||
|
||||
private OnPrintersChangeListener mListener;
|
||||
|
||||
private boolean mIsPrinterDiscoveryStarted;
|
||||
|
||||
public static interface OnPrintersChangeListener {
|
||||
public void onPrintersChanged();
|
||||
}
|
||||
|
||||
PrinterDiscoverySession(IPrintManager printManager, Context context, int userId) {
|
||||
mPrintManager = printManager;
|
||||
mUserId = userId;
|
||||
mHandler = new SessionHandler(context.getMainLooper());
|
||||
mObserver = new PrinterDiscoveryObserver(this);
|
||||
try {
|
||||
mPrintManager.createPrinterDiscoverySession(mObserver, mUserId);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error creating printer discovery session", re);
|
||||
}
|
||||
}
|
||||
|
||||
public final void startPrinterDisovery(List<PrinterId> priorityList) {
|
||||
if (isDestroyed()) {
|
||||
Log.w(LOG_TAG, "Ignoring start printers dsicovery - session destroyed");
|
||||
}
|
||||
if (!mIsPrinterDiscoveryStarted) {
|
||||
mIsPrinterDiscoveryStarted = true;
|
||||
try {
|
||||
mPrintManager.startPrinterDiscovery(mObserver, priorityList, mUserId);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error starting printer discovery", re);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void stopPrinterDiscovery() {
|
||||
if (isDestroyed()) {
|
||||
Log.w(LOG_TAG, "Ignoring stop printers discovery - session destroyed");
|
||||
}
|
||||
if (mIsPrinterDiscoveryStarted) {
|
||||
mIsPrinterDiscoveryStarted = false;
|
||||
try {
|
||||
mPrintManager.stopPrinterDiscovery(mObserver, mUserId);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error stopping printer discovery", re);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void requestPrinterUpdate(PrinterId printerId) {
|
||||
if (isDestroyed()) {
|
||||
Log.w(LOG_TAG, "Ignoring reqeust printer update - session destroyed");
|
||||
}
|
||||
try {
|
||||
mPrintManager.requestPrinterUpdate(printerId, mUserId);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error requesting printer update", re);
|
||||
}
|
||||
}
|
||||
|
||||
public final void destroy() {
|
||||
if (isDestroyed()) {
|
||||
Log.w(LOG_TAG, "Ignoring destroy - session destroyed");
|
||||
}
|
||||
destroyNoCheck();
|
||||
}
|
||||
|
||||
public final List<PrinterInfo> getPrinters() {
|
||||
if (isDestroyed()) {
|
||||
Log.w(LOG_TAG, "Ignoring get printers - session destroyed");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ArrayList<PrinterInfo>(mPrinters.values());
|
||||
}
|
||||
|
||||
public final boolean isDestroyed() {
|
||||
throwIfNotCalledOnMainThread();
|
||||
return isDestroyedNoCheck();
|
||||
}
|
||||
|
||||
public final boolean isPrinterDiscoveryStarted() {
|
||||
throwIfNotCalledOnMainThread();
|
||||
return mIsPrinterDiscoveryStarted;
|
||||
}
|
||||
|
||||
public final void setOnPrintersChangeListener(OnPrintersChangeListener listener) {
|
||||
throwIfNotCalledOnMainThread();
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void finalize() throws Throwable {
|
||||
if (!isDestroyedNoCheck()) {
|
||||
Log.e(LOG_TAG, "Destroying leaked printer discovery session");
|
||||
destroyNoCheck();
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
private boolean isDestroyedNoCheck() {
|
||||
return (mObserver == null);
|
||||
}
|
||||
|
||||
private void destroyNoCheck() {
|
||||
stopPrinterDiscovery();
|
||||
try {
|
||||
mPrintManager.destroyPrinterDiscoverySession(mObserver, mUserId);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error destroying printer discovery session", re);
|
||||
} finally {
|
||||
mObserver = null;
|
||||
mPrinters.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePrintersAdded(List<PrinterInfo> printers) {
|
||||
if (isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
boolean printersChanged = false;
|
||||
final int addedPrinterCount = printers.size();
|
||||
for (int i = 0; i < addedPrinterCount; i++) {
|
||||
PrinterInfo addedPrinter = printers.get(i);
|
||||
if (mPrinters.get(addedPrinter.getId()) == null) {
|
||||
mPrinters.put(addedPrinter.getId(), addedPrinter);
|
||||
printersChanged = true;
|
||||
}
|
||||
}
|
||||
if (printersChanged) {
|
||||
notifyOnPrintersChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePrintersRemoved(List<PrinterId> printerIds) {
|
||||
if (isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
boolean printersChanged = false;
|
||||
final int removedPrinterIdCount = printerIds.size();
|
||||
for (int i = 0; i < removedPrinterIdCount; i++) {
|
||||
PrinterId removedPrinterId = printerIds.get(i);
|
||||
if (mPrinters.remove(removedPrinterId) != null) {
|
||||
printersChanged = true;
|
||||
}
|
||||
}
|
||||
if (printersChanged) {
|
||||
notifyOnPrintersChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePrintersUpdated(List<PrinterInfo> printers) {
|
||||
if (isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
boolean printersChanged = false;
|
||||
final int updatedPrinterCount = printers.size();
|
||||
for (int i = 0; i < updatedPrinterCount; i++) {
|
||||
PrinterInfo updatedPrinter = printers.get(i);
|
||||
PrinterInfo oldPrinter = mPrinters.get(updatedPrinter.getId());
|
||||
if (oldPrinter != null && !oldPrinter.equals(updatedPrinter)) {
|
||||
mPrinters.put(updatedPrinter.getId(), updatedPrinter);
|
||||
printersChanged = true;
|
||||
}
|
||||
}
|
||||
if (printersChanged) {
|
||||
notifyOnPrintersChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyOnPrintersChanged() {
|
||||
if (mListener != null) {
|
||||
mListener.onPrintersChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private static void throwIfNotCalledOnMainThread() {
|
||||
if (!Looper.getMainLooper().isCurrentThread()) {
|
||||
throw new IllegalAccessError("must be called from the main thread");
|
||||
}
|
||||
}
|
||||
|
||||
private final class SessionHandler extends Handler {
|
||||
|
||||
public SessionHandler(Looper looper) {
|
||||
super(looper, null, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case MSG_PRINTERS_ADDED: {
|
||||
List<PrinterInfo> printers = (List<PrinterInfo>) message.obj;
|
||||
handlePrintersAdded(printers);
|
||||
} break;
|
||||
|
||||
case MSG_PRINTERS_REMOVED: {
|
||||
List<PrinterId> printerIds = (List<PrinterId>) message.obj;
|
||||
handlePrintersRemoved(printerIds);
|
||||
} break;
|
||||
|
||||
case MSG_PRINTERS_UPDATED: {
|
||||
List<PrinterInfo> printers = (List<PrinterInfo>) message.obj;
|
||||
handlePrintersUpdated(printers);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class PrinterDiscoveryObserver extends IPrinterDiscoveryObserver.Stub {
|
||||
|
||||
private final WeakReference<PrinterDiscoverySession> mWeakSession;
|
||||
|
||||
public PrinterDiscoveryObserver(PrinterDiscoverySession session) {
|
||||
mWeakSession = new WeakReference<PrinterDiscoverySession>(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersAdded(List<PrinterInfo> printers) {
|
||||
PrinterDiscoverySession session = mWeakSession.get();
|
||||
if (session != null) {
|
||||
session.mHandler.obtainMessage(MSG_PRINTERS_ADDED,
|
||||
printers).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersRemoved(List<PrinterId> printerIds) {
|
||||
PrinterDiscoverySession session = mWeakSession.get();
|
||||
if (session != null) {
|
||||
session.mHandler.obtainMessage(MSG_PRINTERS_REMOVED,
|
||||
printerIds).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersUpdated(List<PrinterInfo> printers) {
|
||||
PrinterDiscoverySession session = mWeakSession.get();
|
||||
if (session != null) {
|
||||
session.mHandler.obtainMessage(MSG_PRINTERS_UPDATED,
|
||||
printers).sendToTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,12 @@
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.printspooler"
|
||||
android:sharedUserId="android.uid.system"
|
||||
android:sharedUserId="android.uid.printspooler"
|
||||
android:versionName="1"
|
||||
android:versionCode="1"
|
||||
coreApp="true">
|
||||
|
||||
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="17"/>
|
||||
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="18"/>
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_ALL_PRINT_JOBS"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
@@ -36,7 +36,8 @@
|
||||
<application
|
||||
android:allowClearUserData="false"
|
||||
android:label="@string/app_label"
|
||||
android:allowBackup= "false">
|
||||
android:allowBackup= "false"
|
||||
android:supportsRtl="true">
|
||||
|
||||
<service
|
||||
android:name=".PrintSpoolerService"
|
||||
@@ -46,6 +47,7 @@
|
||||
|
||||
<activity
|
||||
android:name=".PrintJobConfigActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:exported="false"
|
||||
android:theme="@style/PrintJobConfigActivityTheme">
|
||||
</activity>
|
||||
|
||||
@@ -14,208 +14,234 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/content_editing"
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
android:background="@color/editable_background">
|
||||
|
||||
<ScrollView
|
||||
<GridLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
android:background="@color/editable_background">
|
||||
android:columnCount="2">
|
||||
|
||||
<GridLayout
|
||||
android:layout_width="wrap_content"
|
||||
<!-- Destination -->
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/destination_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
android:layout_marginTop="24dip"
|
||||
android:layout_marginStart="24dip"
|
||||
android:layout_marginEnd="24dip"
|
||||
android:layout_row="0"
|
||||
android:layout_column="0"
|
||||
android:layout_columnSpan="2"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall">
|
||||
</Spinner>
|
||||
|
||||
<!-- Copies -->
|
||||
|
||||
<view
|
||||
class="com.android.printspooler.PrintJobConfigActivity$CustomEditText"
|
||||
android:id="@+id/copies_edittext"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dip"
|
||||
android:layout_marginTop="32dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="2"
|
||||
android:layout_column="0"
|
||||
android:layout_gravity="bottom|fill_horizontal"
|
||||
style="@style/PrintOptionEditTextStyle"
|
||||
android:inputType="numberDecimal">
|
||||
</view>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="36dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="1"
|
||||
android:layout_column="0"
|
||||
android:layout_gravity="start|bottom"
|
||||
style="@style/PrintOptionTextViewStyle"
|
||||
android:labelFor="@id/copies_edittext"
|
||||
android:text="@string/label_copies">
|
||||
</TextView>
|
||||
|
||||
<!-- Paper size -->
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/paper_size_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dip"
|
||||
android:layout_marginEnd="24dip"
|
||||
android:layout_marginBottom="24dip"
|
||||
android:orientation="vertical"
|
||||
android:columnCount="2">
|
||||
android:layout_row="2"
|
||||
android:layout_column="1"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
style="@style/PrintOptionSpinnerStyle">
|
||||
</Spinner>
|
||||
|
||||
<!-- Destination -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="18dip"
|
||||
android:layout_marginEnd="24dip"
|
||||
android:layout_row="1"
|
||||
android:layout_column="1"
|
||||
style="@style/PrintOptionTextViewStyle"
|
||||
android:labelFor="@id/paper_size_spinner"
|
||||
android:text="@string/label_paper_size">
|
||||
</TextView>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/destination_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
android:layout_row="0"
|
||||
android:layout_column="0"
|
||||
android:layout_columnSpan="2"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall">
|
||||
</Spinner>
|
||||
<!-- Color -->
|
||||
|
||||
<!-- Copies -->
|
||||
<Spinner
|
||||
android:id="@+id/color_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="4"
|
||||
android:layout_column="0"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
style="@style/PrintOptionSpinnerStyle">
|
||||
</Spinner>
|
||||
|
||||
<view
|
||||
class="com.android.printspooler.PrintJobConfigActivity$CustomEditText"
|
||||
android:id="@+id/copies_edittext"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="2"
|
||||
android:layout_column="0"
|
||||
android:layout_gravity="bottom"
|
||||
android:inputType="numberDecimal"
|
||||
android:selectAllOnFocus="true"
|
||||
android:minWidth="150dip"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall">
|
||||
</view>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="36dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="3"
|
||||
android:layout_column="0"
|
||||
style="@style/PrintOptionTextViewStyle"
|
||||
android:labelFor="@id/color_spinner"
|
||||
android:text="@string/label_color">
|
||||
</TextView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="12dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="1"
|
||||
android:layout_column="0"
|
||||
android:layout_gravity="start|bottom"
|
||||
android:labelFor="@id/copies_edittext"
|
||||
android:text="@string/label_copies"
|
||||
android:textAppearance="@style/PrintOptionTitleTextAppearance">
|
||||
</TextView>
|
||||
<!-- Orientation -->
|
||||
|
||||
<!-- Paper size -->
|
||||
<Spinner
|
||||
android:id="@+id/orientation_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dip"
|
||||
android:layout_marginEnd="24dip"
|
||||
android:layout_row="4"
|
||||
android:layout_column="1"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
style="@style/PrintOptionSpinnerStyle">
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/paper_size_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dip"
|
||||
android:layout_row="2"
|
||||
android:layout_column="1"
|
||||
style="@style/PrintOptionSpinnerStyle">
|
||||
</Spinner>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="18dip"
|
||||
android:layout_marginEnd="24dip"
|
||||
android:layout_row="3"
|
||||
android:layout_column="1"
|
||||
style="@style/PrintOptionTextViewStyle"
|
||||
android:labelFor="@id/orientation_spinner"
|
||||
android:text="@string/label_orientation">
|
||||
</TextView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="18dip"
|
||||
android:layout_row="1"
|
||||
android:layout_column="1"
|
||||
android:labelFor="@id/paper_size_spinner"
|
||||
android:text="@string/label_paper_size"
|
||||
android:textAppearance="@style/PrintOptionTitleTextAppearance">
|
||||
</TextView>
|
||||
<!-- Range options -->
|
||||
|
||||
<!-- Color -->
|
||||
<Spinner
|
||||
android:id="@+id/range_options_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="6"
|
||||
android:layout_column="0"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
style="@style/PrintOptionSpinnerStyle">
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/color_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="4"
|
||||
android:layout_column="0"
|
||||
style="@style/PrintOptionSpinnerStyle">
|
||||
</Spinner>
|
||||
<TextView
|
||||
android:id="@+id/range_options_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="36dip"
|
||||
android:layout_row="5"
|
||||
android:layout_column="0"
|
||||
style="@style/PrintOptionTextViewStyle"
|
||||
android:labelFor="@id/range_options_spinner"
|
||||
android:text="@string/label_pages">
|
||||
</TextView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="12dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="3"
|
||||
android:layout_column="0"
|
||||
android:labelFor="@id/color_spinner"
|
||||
android:text="@string/label_color"
|
||||
android:textAppearance="@style/PrintOptionTitleTextAppearance">
|
||||
</TextView>
|
||||
<!-- Pages -->
|
||||
|
||||
<!-- Orientation -->
|
||||
<view
|
||||
class="com.android.printspooler.PrintJobConfigActivity$CustomEditText"
|
||||
android:id="@+id/page_range_edittext"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dip"
|
||||
android:layout_marginEnd="24dip"
|
||||
android:layout_row="6"
|
||||
android:layout_column="1"
|
||||
android:layout_gravity="bottom|fill_horizontal"
|
||||
style="@style/PrintOptionEditTextStyle"
|
||||
android:visibility="gone"
|
||||
android:inputType="textNoSuggestions">
|
||||
</view>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/orientation_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dip"
|
||||
android:layout_row="4"
|
||||
android:layout_column="1"
|
||||
style="@style/PrintOptionSpinnerStyle">
|
||||
</Spinner>
|
||||
<TextView
|
||||
android:id="@+id/page_range_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="12dip"
|
||||
android:layout_marginEnd="24dip"
|
||||
android:layout_row="5"
|
||||
android:layout_column="1"
|
||||
style="@style/PrintOptionTextViewStyle"
|
||||
android:labelFor="@id/page_range_edittext"
|
||||
android:text="@string/pages_range_example"
|
||||
android:textAllCaps="false">
|
||||
</TextView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="18dip"
|
||||
android:layout_row="3"
|
||||
android:layout_column="1"
|
||||
android:labelFor="@id/orientation_spinner"
|
||||
android:text="@string/label_orientation"
|
||||
android:textAppearance="@style/PrintOptionTitleTextAppearance">
|
||||
</TextView>
|
||||
<!-- Print button -->
|
||||
|
||||
<!-- Pages -->
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="1dip"
|
||||
android:layout_marginTop="24dip"
|
||||
android:layout_row="7"
|
||||
android:layout_column="0"
|
||||
android:layout_columnSpan="2"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
android:background="@color/separator"
|
||||
android:contentDescription="@null">
|
||||
</ImageView>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/range_options_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_row="6"
|
||||
android:layout_column="0"
|
||||
style="@style/PrintOptionSpinnerStyle">
|
||||
</Spinner>
|
||||
<Button
|
||||
android:id="@+id/print_button"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
android:layout_row="8"
|
||||
android:layout_column="0"
|
||||
android:layout_columnSpan="2"
|
||||
android:text="@string/print_button"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/important_text">
|
||||
</Button>
|
||||
|
||||
<view
|
||||
class="com.android.printspooler.PrintJobConfigActivity$CustomEditText"
|
||||
android:id="@+id/page_range_edittext"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="6dip"
|
||||
android:layout_row="6"
|
||||
android:layout_column="1"
|
||||
android:layout_gravity="bottom"
|
||||
android:selectAllOnFocus="true"
|
||||
android:minWidth="150dip"
|
||||
android:hint="@string/pages_range_example"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:visibility="gone"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall">
|
||||
</view>
|
||||
</GridLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/page_range_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dip"
|
||||
android:layout_marginStart="12dip"
|
||||
android:layout_row="5"
|
||||
android:layout_column="0"
|
||||
android:labelFor="@id/range_options_spinner"
|
||||
android:text="@string/label_pages"
|
||||
android:textAppearance="@style/PrintOptionTitleTextAppearance">
|
||||
</TextView>
|
||||
</ScrollView>
|
||||
|
||||
</GridLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="@color/separator">
|
||||
</View>
|
||||
|
||||
<Button
|
||||
android:id="@+id/print_button"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
android:text="@string/print_button"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/important_text">
|
||||
</Button>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
<!-- Label of the print dialog's print button. [CHAR LIMIT=16] -->
|
||||
<string name="print_button">Print</string>
|
||||
|
||||
<!-- Label of the print dialog's save button. [CHAR LIMIT=16] -->
|
||||
<string name="save_button">Save</string>
|
||||
|
||||
<!-- Label of the destination widget. [CHAR LIMIT=20] -->
|
||||
<string name="label_destination">DESTIINATION</string>
|
||||
|
||||
@@ -41,7 +44,7 @@
|
||||
<string name="label_pages">PAGES (<xliff:g id="page_count" example="5">%1$s</xliff:g>)</string>
|
||||
|
||||
<!-- Page range exmple used as a hint of how to specify such. [CHAR LIMIT=15] -->
|
||||
<string name="pages_range_example">e.g. 1–5, 8</string>
|
||||
<string name="pages_range_example">e.g. 1–5, 8, 11–13</string>
|
||||
|
||||
<!-- Title for the pring preview button .[CHAR LIMIT=30] -->
|
||||
<string name="print_preview">Print preview</string>
|
||||
@@ -62,11 +65,7 @@
|
||||
<string name="save_as_pdf">Save as PDF</string>
|
||||
|
||||
<!-- Title for the open all printers UI option in the printer list. [CHAR LIMIT=30] -->
|
||||
<string name="all_printers">All printers\.\.\.</string>
|
||||
|
||||
<!-- Title for the searching for printers option in the printer list
|
||||
(only option if not printers are available). [CHAR LIMIT=40] -->
|
||||
<string name="searching_for_printers">Searching for printers\.\.\.</string>
|
||||
<string name="all_printers">All printers…</string>
|
||||
|
||||
<!-- Select printer activity -->
|
||||
|
||||
|
||||
@@ -27,7 +27,21 @@
|
||||
<item name="android:paddingTop">0dip</item>
|
||||
<item name="android:paddingBottom">0dip</item>
|
||||
<item name="android:minWidth">150dip</item>
|
||||
<item name="android:maxWidth">200dip</item>
|
||||
<item name="android:minHeight">?android:attr/listPreferredItemHeightSmall</item>
|
||||
</style>
|
||||
|
||||
<style name="PrintOptionEditTextStyle">
|
||||
<item name="android:selectAllOnFocus">true</item>
|
||||
<item name="android:minHeight">?android:attr/listPreferredItemHeightSmall</item>
|
||||
<item name="android:maxWidth">200dip</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
</style>
|
||||
|
||||
<style name="PrintOptionTextViewStyle">
|
||||
<item name="android:textAppearance">@style/PrintOptionTitleTextAppearance</item>
|
||||
<item name="android:maxWidth">200dip</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<style name="PrintJobConfigActivityTheme" parent="@android:style/Theme.Holo.Light.NoActionBar">
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:windowSoftInputMode">stateAlwaysHidden|adjustPan</item>
|
||||
<item name="android:windowSoftInputMode">stateAlwaysHidden|adjustResize</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:backgroundDimEnabled">true</item>
|
||||
<item name="android:colorBackgroundCacheHint">@android:color/transparent</item>
|
||||
|
||||
@@ -21,6 +21,9 @@ import android.content.Context;
|
||||
import android.content.Loader;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.print.PrintManager;
|
||||
import android.print.PrinterDiscoverySession;
|
||||
import android.print.PrinterDiscoverySession.OnPrintersChangeListener;
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrinterInfo;
|
||||
import android.util.ArrayMap;
|
||||
@@ -30,7 +33,6 @@ import android.util.Slog;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.printspooler.PrintSpoolerService.PrinterDiscoverySession;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
@@ -62,7 +64,7 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
|
||||
private static final int MAX_HISTORY_LENGTH = 50;
|
||||
|
||||
private static final int MAX_HISTORICAL_PRINTER_COUNT = 4;
|
||||
private static final int MAX_FAVORITE_PRINTER_COUNT = 4;
|
||||
|
||||
private final Map<PrinterId, PrinterInfo> mPrinters =
|
||||
new LinkedHashMap<PrinterId, PrinterInfo>();
|
||||
@@ -96,7 +98,7 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onStartLoading()");
|
||||
Log.i(LOG_TAG, "onStartLoading()" + FusedPrintersProvider.this.hashCode());
|
||||
}
|
||||
// The contract is that if we already have a valid,
|
||||
// result the we have to deliver it immediately.
|
||||
@@ -113,7 +115,7 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
@Override
|
||||
protected void onStopLoading() {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onStopLoading()");
|
||||
Log.i(LOG_TAG, "onStopLoading()" + FusedPrintersProvider.this.hashCode());
|
||||
}
|
||||
onCancelLoad();
|
||||
}
|
||||
@@ -121,7 +123,7 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
@Override
|
||||
protected void onForceLoad() {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onForceLoad()");
|
||||
Log.i(LOG_TAG, "onForceLoad()" + FusedPrintersProvider.this.hashCode());
|
||||
}
|
||||
onCancelLoad();
|
||||
loadInternal();
|
||||
@@ -129,12 +131,21 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
|
||||
private void loadInternal() {
|
||||
if (mDiscoverySession == null) {
|
||||
mDiscoverySession = new MyPrinterDiscoverySession();
|
||||
PrintManager printManager = (PrintManager) getContext()
|
||||
.getSystemService(Context.PRINT_SERVICE);
|
||||
mDiscoverySession = printManager.createPrinterDiscoverySession();
|
||||
mDiscoverySession.setOnPrintersChangeListener(new OnPrintersChangeListener() {
|
||||
@Override
|
||||
public void onPrintersChanged() {
|
||||
deliverResult(new ArrayList<PrinterInfo>(
|
||||
mDiscoverySession.getPrinters()));
|
||||
}
|
||||
});
|
||||
mPersistenceManager.readPrinterHistory();
|
||||
}
|
||||
if (mPersistenceManager.isReadHistoryCompleted()
|
||||
&& !mDiscoverySession.isStarted()) {
|
||||
final int favoriteCount = Math.min(MAX_HISTORICAL_PRINTER_COUNT,
|
||||
&& !mDiscoverySession.isPrinterDiscoveryStarted()) {
|
||||
final int favoriteCount = Math.min(MAX_FAVORITE_PRINTER_COUNT,
|
||||
mFavoritePrinters.size());
|
||||
List<PrinterId> printerIds = new ArrayList<PrinterId>(favoriteCount);
|
||||
for (int i = 0; i < favoriteCount; i++) {
|
||||
@@ -147,13 +158,14 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
@Override
|
||||
protected boolean onCancelLoad() {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onCancelLoad()");
|
||||
Log.i(LOG_TAG, "onCancelLoad()" + FusedPrintersProvider.this.hashCode());
|
||||
}
|
||||
return cancelInternal();
|
||||
}
|
||||
|
||||
private boolean cancelInternal() {
|
||||
if (mDiscoverySession != null && mDiscoverySession.isStarted()) {
|
||||
if (mDiscoverySession != null
|
||||
&& mDiscoverySession.isPrinterDiscoveryStarted()) {
|
||||
mDiscoverySession.stopPrinterDiscovery();
|
||||
return true;
|
||||
} else if (mPersistenceManager.isReadHistoryInProgress()) {
|
||||
@@ -165,7 +177,7 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
@Override
|
||||
protected void onReset() {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onReset()");
|
||||
Log.i(LOG_TAG, "onReset()" + FusedPrintersProvider.this.hashCode());
|
||||
}
|
||||
onStopLoading();
|
||||
mPrinters.clear();
|
||||
@@ -178,73 +190,15 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
@Override
|
||||
protected void onAbandon() {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onAbandon()");
|
||||
Log.i(LOG_TAG, "onAbandon()" + FusedPrintersProvider.this.hashCode());
|
||||
}
|
||||
onStopLoading();
|
||||
}
|
||||
|
||||
public void refreshPrinter(PrinterId printerId) {
|
||||
if (isStarted() && mDiscoverySession != null && mDiscoverySession.isStarted()) {
|
||||
mDiscoverySession.requestPrinterUpdated(printerId);
|
||||
}
|
||||
}
|
||||
|
||||
private final class MyPrinterDiscoverySession extends PrinterDiscoverySession {
|
||||
|
||||
@Override
|
||||
public void onPrintersAdded(List<PrinterInfo> printers) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "MyPrinterDiscoverySession#onPrintersAdded()");
|
||||
}
|
||||
boolean printersAdded = false;
|
||||
final int addedPrinterCount = printers.size();
|
||||
for (int i = 0; i < addedPrinterCount; i++) {
|
||||
PrinterInfo printer = printers.get(i);
|
||||
if (!mPrinters.containsKey(printer.getId())) {
|
||||
mPrinters.put(printer.getId(), printer);
|
||||
printersAdded = true;
|
||||
}
|
||||
}
|
||||
if (printersAdded) {
|
||||
deliverResult(new ArrayList<PrinterInfo>(mPrinters.values()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersRemoved(List<PrinterId> printerIds) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "MyPrinterDiscoverySession#onPrintersRemoved()");
|
||||
}
|
||||
boolean removedPrinters = false;
|
||||
final int removedPrinterCount = printerIds.size();
|
||||
for (int i = 0; i < removedPrinterCount; i++) {
|
||||
PrinterId removedPrinterId = printerIds.get(i);
|
||||
if (mPrinters.remove(removedPrinterId) != null) {
|
||||
removedPrinters = true;
|
||||
}
|
||||
}
|
||||
if (removedPrinters) {
|
||||
deliverResult(new ArrayList<PrinterInfo>(mPrinters.values()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersUpdated(List<PrinterInfo> printers) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "MyPrinterDiscoverySession#onPrintersUpdated()");
|
||||
}
|
||||
boolean updatedPrinters = false;
|
||||
final int updatedPrinterCount = printers.size();
|
||||
for (int i = 0; i < updatedPrinterCount; i++) {
|
||||
PrinterInfo updatedPrinter = printers.get(i);
|
||||
if (mPrinters.containsKey(updatedPrinter.getId())) {
|
||||
mPrinters.put(updatedPrinter.getId(), updatedPrinter);
|
||||
updatedPrinters = true;
|
||||
}
|
||||
}
|
||||
if (updatedPrinters) {
|
||||
deliverResult(new ArrayList<PrinterInfo>(mPrinters.values()));
|
||||
}
|
||||
if (isStarted() && mDiscoverySession != null
|
||||
&& mDiscoverySession.isPrinterDiscoveryStarted()) {
|
||||
mDiscoverySession.requestPrinterUpdate(printerId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +234,7 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
@Override
|
||||
protected void onPostExecute(List<PrinterInfo> printers) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "read history completed");
|
||||
Log.i(LOG_TAG, "read history completed" + FusedPrintersProvider.this.hashCode());
|
||||
}
|
||||
|
||||
mHistoricalPrinters = printers;
|
||||
@@ -290,7 +244,7 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
|
||||
// We want the first few favorite printers on top of the list.
|
||||
final int favoriteCount = Math.min(mFavoritePrinters.size(),
|
||||
MAX_HISTORICAL_PRINTER_COUNT);
|
||||
MAX_FAVORITE_PRINTER_COUNT);
|
||||
for (int i = 0; i < favoriteCount; i++) {
|
||||
PrinterInfo favoritePrinter = mFavoritePrinters.get(i);
|
||||
mPrinters.put(favoritePrinter.getId(), favoritePrinter);
|
||||
@@ -299,6 +253,10 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
|
||||
mReadHistoryInProgress = false;
|
||||
mReadHistoryCompleted = true;
|
||||
|
||||
// Deliver the favorites.
|
||||
deliverResult(mFavoritePrinters);
|
||||
|
||||
// Start loading the available printers.
|
||||
loadInternal();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@ import android.view.View.MeasureSpec;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
@@ -111,15 +110,10 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
private static final int LOADER_ID_PRINTERS_LOADER = 1;
|
||||
|
||||
private static final int DEST_ADAPTER_MIN_ITEM_COUNT = 2;
|
||||
private static final int DEST_ADAPTER_MAX_ITEM_COUNT = 9;
|
||||
|
||||
private static final int DEST_ADAPTER_POSITION_SEARCHING_FOR_PRINTERS = 0;
|
||||
private static final int DEST_ADAPTER_POSITION_SAVE_AS_PDF = 1;
|
||||
|
||||
private static final int DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF = Integer.MAX_VALUE;
|
||||
private static final int DEST_ADAPTER_ITEM_ID_ALL_PRINTERS = Integer.MAX_VALUE - 1;
|
||||
private static final int DEST_ADAPTER_ITEM_ID_SEARCHING_FOR_PRINTERS = Integer.MAX_VALUE - 2;
|
||||
|
||||
private static final int ACTIVITY_REQUEST_CREATE_FILE = 1;
|
||||
private static final int ACTIVITY_REQUEST_SELECT_PRINTER = 2;
|
||||
@@ -196,15 +190,11 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
setContentView(R.layout.print_job_config_activity_container);
|
||||
|
||||
// TODO: This should be on the style
|
||||
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
||||
|
||||
|
||||
mEditor = new Editor();
|
||||
mDocument = new Document();
|
||||
mController = new PrintController(new RemotePrintDocumentAdapter(
|
||||
IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter),
|
||||
PrintSpoolerService.peekInstance().generateFileForPrintJob(mPrintJobId)));
|
||||
mEditor = new Editor();
|
||||
|
||||
try {
|
||||
mIPrintDocumentAdapter.linkToDeath(mDeathRecipient, 0);
|
||||
@@ -217,6 +207,12 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mEditor.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mEditor.refreshCurrentPrinter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
// We can safely do the work in here since at this point
|
||||
@@ -294,6 +290,8 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
private int mControllerState = CONTROLLER_STATE_INITIALIZED;
|
||||
|
||||
private boolean mHasStarted;
|
||||
|
||||
private PageRange[] mRequestedPages;
|
||||
|
||||
public PrintController(RemotePrintDocumentAdapter adapter) {
|
||||
@@ -305,6 +303,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
mHasStarted = false;
|
||||
mControllerState = CONTROLLER_STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
@@ -321,7 +320,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
}
|
||||
|
||||
public boolean hasStarted() {
|
||||
return mControllerState >= CONTROLLER_STATE_STARTED;
|
||||
return mHasStarted;
|
||||
}
|
||||
|
||||
public boolean hasPerformedLayout() {
|
||||
@@ -335,10 +334,14 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
public void start() {
|
||||
mControllerState = CONTROLLER_STATE_STARTED;
|
||||
mHasStarted = true;
|
||||
mRemotePrintAdapter.start();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (!mController.hasStarted()) {
|
||||
mController.start();
|
||||
}
|
||||
if (!printAttributesChanged()) {
|
||||
// If the attributes changed, then we do not do a layout but may
|
||||
// have to ask the app to write some pages. Hence, pretend layout
|
||||
@@ -372,6 +375,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
}
|
||||
|
||||
if (isCancelled()) {
|
||||
mEditor.updateUi();
|
||||
if (mEditor.isDone()) {
|
||||
PrintJobConfigActivity.this.finish();
|
||||
}
|
||||
@@ -379,7 +383,6 @@ public class PrintJobConfigActivity extends Activity {
|
||||
}
|
||||
|
||||
mControllerState = CONTROLLER_STATE_LAYOUT_COMPLETED;
|
||||
mEditor.updateUi();
|
||||
|
||||
// If the info changed, we update the document and the print job.
|
||||
final boolean infoChanged = !info.equals(mDocument.info);
|
||||
@@ -402,6 +405,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
// trigger an update.
|
||||
mRequestedPages = mEditor.getRequestedPages();
|
||||
if (mRequestedPages == null) {
|
||||
mEditor.updateUi();
|
||||
if (mEditor.isDone()) {
|
||||
PrintJobConfigActivity.this.finish();
|
||||
}
|
||||
@@ -423,12 +427,15 @@ public class PrintJobConfigActivity extends Activity {
|
||||
// preview button, then just skip the write.
|
||||
if (!LIVE_PREVIEW_SUPPORTED && !mEditor.isPreviewConfirmed()
|
||||
&& mMetadata.getBoolean(PrintDocumentAdapter.METADATA_KEY_PRINT_PREVIEW)) {
|
||||
mEditor.updateUi();
|
||||
if (mEditor.isDone()) {
|
||||
PrintJobConfigActivity.this.finish();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mEditor.updateUi();
|
||||
|
||||
// Request a write of the pages of interest.
|
||||
mControllerState = CONTROLLER_STATE_WRITE_STARTED;
|
||||
mRemotePrintAdapter.write(mRequestedPages, mWriteResultCallback,
|
||||
@@ -647,7 +654,6 @@ public class PrintJobConfigActivity extends Activity {
|
||||
if (resultCode == RESULT_OK) {
|
||||
PrinterId printerId = (PrinterId) data.getParcelableExtra(
|
||||
INTENT_EXTRA_PRINTER_ID);
|
||||
// TODO: Make sure the selected printer is in the shown list.
|
||||
mEditor.selectPrinter(printerId);
|
||||
}
|
||||
} break;
|
||||
@@ -704,8 +710,9 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
private EditText mCopiesEditText;
|
||||
|
||||
private TextView mRangeTitle;
|
||||
private EditText mRangeEditText;
|
||||
private TextView mRangeOptionsTitle;
|
||||
private TextView mPageRangeTitle;
|
||||
private EditText mPageRangeEditText;
|
||||
|
||||
private Spinner mDestinationSpinner;
|
||||
private final DestinationAdapter mDestinationSpinnerAdapter;
|
||||
@@ -729,6 +736,8 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
private Button mPrintButton;
|
||||
|
||||
private PrinterInfo mCurrentPrinter;
|
||||
|
||||
private final OnItemSelectedListener mOnItemSelectedListener =
|
||||
new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
@@ -738,69 +747,37 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mIgnoreNextDestinationChange = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == DEST_ADAPTER_ITEM_ID_ALL_PRINTERS) {
|
||||
mIgnoreNextDestinationChange = true;
|
||||
mDestinationSpinner.setSelection(0);
|
||||
Intent intent = new Intent(PrintJobConfigActivity.this,
|
||||
SelectPrinterActivity.class);
|
||||
startActivityForResult(intent, ACTIVITY_REQUEST_SELECT_PRINTER);
|
||||
startSelectPrinterActivity();
|
||||
return;
|
||||
}
|
||||
mWaitingForPrinterCapabilities = false;
|
||||
|
||||
mCurrPrintAttributes.clear();
|
||||
|
||||
PrinterInfo printer = (PrinterInfo) mDestinationSpinnerAdapter
|
||||
.getItem(position);
|
||||
|
||||
PrintSpoolerService.peekInstance().setPrintJobPrinterNoPersistence(
|
||||
mPrintJobId, printer);
|
||||
|
||||
if (printer != null) {
|
||||
PrintSpoolerService.peekInstance().setPrintJobPrinterNoPersistence(
|
||||
mPrintJobId, printer);
|
||||
PrinterCapabilitiesInfo capabilities = printer.getCapabilities();
|
||||
if (capabilities == null) {
|
||||
List<PrinterId> printerIds = new ArrayList<PrinterId>();
|
||||
printerIds.add(printer.getId());
|
||||
FusedPrintersProvider printersLoader = (FusedPrintersProvider)
|
||||
(Loader<?>) getLoaderManager().getLoader(
|
||||
LOADER_ID_PRINTERS_LOADER);
|
||||
if (printersLoader != null) {
|
||||
printersLoader.refreshPrinter(printer.getId());
|
||||
}
|
||||
mWaitingForPrinterCapabilities = true;
|
||||
//TODO: We need a timeout for the update.
|
||||
mEditor.refreshCurrentPrinter();
|
||||
} else {
|
||||
capabilities.getDefaults(mCurrPrintAttributes);
|
||||
if (!mController.hasStarted()) {
|
||||
mController.start();
|
||||
}
|
||||
if (!hasErrors()) {
|
||||
mController.update();
|
||||
}
|
||||
mController.update();
|
||||
}
|
||||
}
|
||||
|
||||
// The printer changed so we want to start with a clean slate
|
||||
// for the print options and let them be populated from the
|
||||
// printer capabilities and use the printer defaults.
|
||||
if (!mMediaSizeSpinnerAdapter.isEmpty()) {
|
||||
mIgnoreNextMediaSizeChange = true;
|
||||
mMediaSizeSpinnerAdapter.clear();
|
||||
}
|
||||
if (!mColorModeSpinnerAdapter.isEmpty()) {
|
||||
mIgnoreNextColorModeChange = true;
|
||||
mColorModeSpinnerAdapter.clear();
|
||||
}
|
||||
if (!mOrientationSpinnerAdapter.isEmpty()) {
|
||||
mIgnoreNextOrientationChange = true;
|
||||
mOrientationSpinnerAdapter.clear();
|
||||
}
|
||||
if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
|
||||
mIgnoreNextRangeOptionChange = true;
|
||||
mRangeOptionsSpinner.setSelection(0);
|
||||
}
|
||||
if (!TextUtils.isEmpty(mCopiesEditText.getText())) {
|
||||
mIgnoreNextCopiesChange = true;
|
||||
mCopiesEditText.setText(MIN_COPIES_STRING);
|
||||
}
|
||||
mCurrentPrinter = printer;
|
||||
|
||||
updateUi();
|
||||
updateUiForNewPrinterCapabilities();
|
||||
} else if (spinner == mMediaSizeSpinner) {
|
||||
if (mIgnoreNextMediaSizeChange) {
|
||||
mIgnoreNextMediaSizeChange = false;
|
||||
@@ -877,7 +854,13 @@ public class PrintJobConfigActivity extends Activity {
|
||||
return;
|
||||
}
|
||||
|
||||
final int copies = Integer.parseInt(editable.toString());
|
||||
int copies = 0;
|
||||
try {
|
||||
copies = Integer.parseInt(editable.toString());
|
||||
} catch (NumberFormatException nfe) {
|
||||
/* ignore */
|
||||
}
|
||||
|
||||
if (copies < MIN_COPIES) {
|
||||
mCopiesEditText.setError("");
|
||||
updateUi();
|
||||
@@ -918,14 +901,14 @@ public class PrintJobConfigActivity extends Activity {
|
||||
String text = editable.toString();
|
||||
|
||||
if (TextUtils.isEmpty(text)) {
|
||||
mRangeEditText.setError("");
|
||||
mPageRangeEditText.setError("");
|
||||
updateUi();
|
||||
return;
|
||||
}
|
||||
|
||||
String escapedText = PATTERN_ESCAPE_SPECIAL_CHARS.matcher(text).replaceAll("////");
|
||||
if (!PATTERN_PAGE_RANGE.matcher(escapedText).matches()) {
|
||||
mRangeEditText.setError("");
|
||||
mPageRangeEditText.setError("");
|
||||
updateUi();
|
||||
return;
|
||||
}
|
||||
@@ -935,7 +918,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
String numericString = text.substring(matcher.start(), matcher.end());
|
||||
final int pageIndex = Integer.parseInt(numericString);
|
||||
if (pageIndex < 1 || pageIndex > mDocument.info.getPageCount()) {
|
||||
mRangeEditText.setError("");
|
||||
mPageRangeEditText.setError("");
|
||||
updateUi();
|
||||
return;
|
||||
}
|
||||
@@ -943,7 +926,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
//TODO: Catch the error if start is less grater than the end.
|
||||
|
||||
mRangeEditText.setError(null);
|
||||
mPageRangeEditText.setError(null);
|
||||
mPrintButton.setEnabled(true);
|
||||
updateUi();
|
||||
|
||||
@@ -963,45 +946,70 @@ public class PrintJobConfigActivity extends Activity {
|
||||
private boolean mIgnoreNextCopiesChange;
|
||||
private boolean mIgnoreNextRangeChange;
|
||||
|
||||
private boolean mWaitingForPrinterCapabilities;
|
||||
|
||||
private int mCurrentUi = UI_NONE;
|
||||
|
||||
private boolean mFavoritePrinterSelected;
|
||||
|
||||
public Editor() {
|
||||
// Destination.
|
||||
mDestinationSpinnerAdapter = new DestinationAdapter();
|
||||
mDestinationSpinnerAdapter.registerDataSetObserver(new DataSetObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
final int selectedPosition = mDestinationSpinner.getSelectedItemPosition();
|
||||
if (mDestinationSpinnerAdapter.getCount() > 0) {
|
||||
// Make sure we select the first printer if we have data.
|
||||
if (selectedPosition == AdapterView.INVALID_POSITION) {
|
||||
mDestinationSpinner.setSelection(0);
|
||||
}
|
||||
} else {
|
||||
// Make sure we select no printer if we have no data.
|
||||
mDestinationSpinner.setSelection(AdapterView.INVALID_POSITION);
|
||||
// Initially, we have only sage to PDF as a printer but after some
|
||||
// printers are loaded we want to select the user's favorite one
|
||||
// which is the first.
|
||||
if (!mFavoritePrinterSelected && mDestinationSpinnerAdapter.getCount() > 2) {
|
||||
mFavoritePrinterSelected = true;
|
||||
mDestinationSpinner.setSelection(0);
|
||||
}
|
||||
|
||||
// Maybe we did not have capabilities when the current printer was
|
||||
// selected, but now the selected printer has capabilities. Generate
|
||||
// a fake selection so the code in the selection change handling takes
|
||||
// care of updating everything. This way the logic is in one place.
|
||||
if (mWaitingForPrinterCapabilities) {
|
||||
mWaitingForPrinterCapabilities = false;
|
||||
PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
|
||||
if (printer != null && printer.getCapabilities() != null) {
|
||||
mOnItemSelectedListener.onItemSelected(mDestinationSpinner, null,
|
||||
selectedPosition, selectedPosition);
|
||||
// If the current printer properties changed, we update the UI.
|
||||
if (mCurrentPrinter != null) {
|
||||
final int printerCount = mDestinationSpinnerAdapter.getCount();
|
||||
for (int i = 0; i < printerCount; i++) {
|
||||
Object item = mDestinationSpinnerAdapter.getItem(i);
|
||||
// Some items are not printers
|
||||
if (item instanceof PrinterInfo) {
|
||||
PrinterInfo printer = (PrinterInfo) item;
|
||||
if (!printer.getId().equals(mCurrentPrinter.getId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update the UI if capabilities changed.
|
||||
boolean capabilitiesChanged = false;
|
||||
|
||||
if (mCurrentPrinter.getCapabilities() == null) {
|
||||
if (printer.getCapabilities() != null) {
|
||||
capabilitiesChanged = true;
|
||||
}
|
||||
} else if (!mCurrentPrinter.getCapabilities().equals(
|
||||
printer.getCapabilities())) {
|
||||
capabilitiesChanged = true;
|
||||
}
|
||||
|
||||
if (capabilitiesChanged) {
|
||||
// Update the current printer.
|
||||
mCurrentPrinter.copyFrom(printer);
|
||||
|
||||
// If something changed during UI update...
|
||||
if (updateUi()) {
|
||||
// Update current attributes.
|
||||
printer.getCapabilities().getDefaults(mCurrPrintAttributes);
|
||||
// Update the document.
|
||||
mController.update();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInvalidated() {
|
||||
updateUi();
|
||||
updateUiForNewPrinterCapabilities();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1039,17 +1047,24 @@ public class PrintJobConfigActivity extends Activity {
|
||||
updateUi();
|
||||
}
|
||||
|
||||
public void selectPrinter(PrinterId printerId) {
|
||||
final int printerCount = mDestinationSpinnerAdapter.getCount();
|
||||
for (int i = 0; i < printerCount; i++) {
|
||||
PrinterInfo printer = (PrinterInfo) mDestinationSpinnerAdapter.getItem(i);
|
||||
if (printer.getId().equals(printerId)) {
|
||||
mDestinationSpinner.setSelection(i);
|
||||
return;
|
||||
public void refreshCurrentPrinter() {
|
||||
PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
|
||||
if (printer != null) {
|
||||
FusedPrintersProvider printersLoader = (FusedPrintersProvider)
|
||||
(Loader<?>) getLoaderManager().getLoader(
|
||||
LOADER_ID_PRINTERS_LOADER);
|
||||
if (printersLoader != null) {
|
||||
printersLoader.refreshPrinter(printer.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void selectPrinter(PrinterId printerId) {
|
||||
mDestinationSpinnerAdapter.ensurePrinterShownPrinterShown(printerId);
|
||||
final int position = mDestinationSpinnerAdapter.getPrinterIndex(printerId);
|
||||
mDestinationSpinner.setSelection(position);
|
||||
}
|
||||
|
||||
public boolean isPrintingToPdf() {
|
||||
return mDestinationSpinner.getSelectedItem()
|
||||
== mDestinationSpinnerAdapter.mFakePdfPrinter;
|
||||
@@ -1163,12 +1178,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mEditor.confirmPrint();
|
||||
mController.update();
|
||||
if (!printer.equals(mDestinationSpinnerAdapter.mFakePdfPrinter)) {
|
||||
FusedPrintersProvider printersLoader = (FusedPrintersProvider)
|
||||
(Loader<?>) getLoaderManager().getLoader(
|
||||
LOADER_ID_PRINTERS_LOADER);
|
||||
if (printersLoader != null) {
|
||||
printersLoader.addHistoricalPrinter(printer);
|
||||
}
|
||||
mEditor.refreshCurrentPrinter();
|
||||
}
|
||||
} else {
|
||||
mEditor.cancel();
|
||||
@@ -1288,7 +1298,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
}
|
||||
if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
|
||||
List<PageRange> pageRanges = new ArrayList<PageRange>();
|
||||
mStringCommaSplitter.setString(mRangeEditText.getText().toString());
|
||||
mStringCommaSplitter.setString(mPageRangeEditText.getText().toString());
|
||||
|
||||
while (mStringCommaSplitter.hasNext()) {
|
||||
String range = mStringCommaSplitter.next().trim();
|
||||
@@ -1340,7 +1350,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mDestinationSpinner = (Spinner) findViewById(R.id.destination_spinner);
|
||||
mDestinationSpinner.setAdapter(mDestinationSpinnerAdapter);
|
||||
mDestinationSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
|
||||
if (mDestinationSpinnerAdapter.getCount() > 0) {
|
||||
if (mDestinationSpinnerAdapter.getCount() > 0 && mController.hasStarted()) {
|
||||
mIgnoreNextDestinationChange = true;
|
||||
}
|
||||
|
||||
@@ -1368,12 +1378,8 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mIgnoreNextOrientationChange = true;
|
||||
}
|
||||
|
||||
// Range
|
||||
mRangeTitle = (TextView) findViewById(R.id.page_range_title);
|
||||
mRangeEditText = (EditText) findViewById(R.id.page_range_edittext);
|
||||
mRangeEditText.addTextChangedListener(mRangeTextWatcher);
|
||||
|
||||
// Range options
|
||||
mRangeOptionsTitle = (TextView) findViewById(R.id.range_options_title);
|
||||
mRangeOptionsSpinner = (Spinner) findViewById(R.id.range_options_spinner);
|
||||
mRangeOptionsSpinner.setAdapter(mRangeOptionsSpinnerAdapter);
|
||||
mRangeOptionsSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
|
||||
@@ -1381,14 +1387,19 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mIgnoreNextRangeOptionChange = true;
|
||||
}
|
||||
|
||||
// Page range
|
||||
mPageRangeTitle = (TextView) findViewById(R.id.page_range_title);
|
||||
mPageRangeEditText = (EditText) findViewById(R.id.page_range_edittext);
|
||||
mPageRangeEditText.addTextChangedListener(mRangeTextWatcher);
|
||||
|
||||
// Print button
|
||||
mPrintButton = (Button) findViewById(R.id.print_button);
|
||||
registerPrintButtonClickListener();
|
||||
}
|
||||
|
||||
public void updateUi() {
|
||||
public boolean updateUi() {
|
||||
if (mCurrentUi != UI_EDITING_PRINT_JOB) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (isPrintConfirmed() || isPreviewConfirmed() || isCancelled()) {
|
||||
mDestinationSpinner.setEnabled(false);
|
||||
@@ -1397,11 +1408,11 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mColorModeSpinner.setEnabled(false);
|
||||
mOrientationSpinner.setEnabled(false);
|
||||
mRangeOptionsSpinner.setEnabled(false);
|
||||
mRangeEditText.setEnabled(false);
|
||||
mPageRangeEditText.setEnabled(false);
|
||||
// TODO: Remove entirely or implement print preview.
|
||||
// mPrintPreviewButton.setEnabled(false);
|
||||
mPrintButton.setEnabled(false);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a printer with capabilities is selected, then we enabled all options.
|
||||
@@ -1452,15 +1463,16 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mRangeOptionsSpinner.setSelection(0);
|
||||
}
|
||||
mRangeOptionsSpinner.setEnabled(false);
|
||||
mRangeTitle.setText(getString(R.string.label_pages,
|
||||
mRangeOptionsTitle.setText(getString(R.string.label_pages,
|
||||
getString(R.string.page_count_unknown)));
|
||||
if (!TextUtils.equals(mRangeEditText.getText(), "")) {
|
||||
if (!TextUtils.equals(mPageRangeEditText.getText(), "")) {
|
||||
mIgnoreNextRangeChange = true;
|
||||
mRangeEditText.setText("");
|
||||
mPageRangeEditText.setText("");
|
||||
}
|
||||
|
||||
mRangeEditText.setEnabled(false);
|
||||
mRangeEditText.setVisibility(View.INVISIBLE);
|
||||
mPageRangeEditText.setEnabled(false);
|
||||
mPageRangeEditText.setVisibility(View.INVISIBLE);
|
||||
mPageRangeTitle.setVisibility(View.INVISIBLE);
|
||||
|
||||
// // Print preview
|
||||
// mPrintPreviewButton.setEnabled(false);
|
||||
@@ -1468,17 +1480,20 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
// Print
|
||||
mPrintButton.setEnabled(false);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
boolean someAttributeSelectionChanged = false;
|
||||
|
||||
PrintAttributes defaultAttributes = mTempPrintAttributes;
|
||||
PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
|
||||
PrinterCapabilitiesInfo capabilities = printer.getCapabilities();
|
||||
printer.getCapabilities().getDefaults(defaultAttributes);
|
||||
|
||||
// Copies
|
||||
mCopiesEditText.setEnabled(true);
|
||||
|
||||
// Media size.
|
||||
List<MediaSize> mediaSizes = capabilities.getMediaSizes();
|
||||
|
||||
// If the media sizes changed, we update the adapter and the spinner.
|
||||
boolean mediaSizesChanged = false;
|
||||
final int mediaSizeCount = mediaSizes.size();
|
||||
if (mediaSizeCount != mMediaSizeSpinnerAdapter.getCount()) {
|
||||
@@ -1492,22 +1507,40 @@ public class PrintJobConfigActivity extends Activity {
|
||||
}
|
||||
}
|
||||
if (mediaSizesChanged) {
|
||||
// Remember the old media size to try selecting it again.
|
||||
int oldMediaSizeNewIndex = AdapterView.INVALID_POSITION;
|
||||
MediaSize oldMediaSize = mCurrPrintAttributes.getMediaSize();
|
||||
|
||||
// Rebuild the adapter data.
|
||||
mMediaSizeSpinnerAdapter.clear();
|
||||
for (int i = 0; i < mediaSizeCount; i++) {
|
||||
MediaSize mediaSize = mediaSizes.get(i);
|
||||
if (mediaSize.equals(oldMediaSize)) {
|
||||
// Update the index of the old selection.
|
||||
oldMediaSizeNewIndex = i;
|
||||
}
|
||||
mMediaSizeSpinnerAdapter.add(new SpinnerItem<MediaSize>(
|
||||
mediaSize, mediaSize.getLabel()));
|
||||
}
|
||||
|
||||
if (mediaSizeCount <= 0) {
|
||||
// No media sizes - clear the selection.
|
||||
mMediaSizeSpinner.setEnabled(false);
|
||||
mMediaSizeSpinner.setSelection(AdapterView.INVALID_POSITION);
|
||||
// Clear selection and mark if selection changed.
|
||||
someAttributeSelectionChanged = setMediaSizeSpinnerSelectionNoCallback(
|
||||
AdapterView.INVALID_POSITION);
|
||||
} else {
|
||||
mMediaSizeSpinner.setEnabled(true);
|
||||
final int selectedMediaSizeIndex = Math.max(mediaSizes.indexOf(
|
||||
defaultAttributes.getMediaSize()), 0);
|
||||
if (mMediaSizeSpinner.getSelectedItemPosition() != selectedMediaSizeIndex) {
|
||||
mIgnoreNextMediaSizeChange = true;
|
||||
mMediaSizeSpinner.setSelection(selectedMediaSizeIndex);
|
||||
|
||||
if (oldMediaSizeNewIndex != AdapterView.INVALID_POSITION) {
|
||||
// Select the old media size - nothing really changed.
|
||||
setMediaSizeSpinnerSelectionNoCallback(oldMediaSizeNewIndex);
|
||||
} else {
|
||||
// Select the first or the default and mark if selection changed.
|
||||
final int mediaSizeIndex = Math.max(mediaSizes.indexOf(
|
||||
defaultAttributes.getMediaSize()), 0);
|
||||
someAttributeSelectionChanged = setMediaSizeSpinnerSelectionNoCallback(
|
||||
mediaSizeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1619,20 +1652,22 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|| info.getPageCount() == PrintDocumentInfo.PAGE_COUNT_UNKNOWN)) {
|
||||
mRangeOptionsSpinner.setEnabled(true);
|
||||
if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
|
||||
if (!mRangeEditText.isEnabled()) {
|
||||
mRangeEditText.setEnabled(true);
|
||||
mRangeEditText.setVisibility(View.VISIBLE);
|
||||
mRangeEditText.requestFocus();
|
||||
if (!mPageRangeEditText.isEnabled()) {
|
||||
mPageRangeEditText.setEnabled(true);
|
||||
mPageRangeEditText.setVisibility(View.VISIBLE);
|
||||
mPageRangeTitle.setVisibility(View.VISIBLE);
|
||||
mPageRangeEditText.requestFocus();
|
||||
InputMethodManager imm = (InputMethodManager)
|
||||
getSystemService(INPUT_METHOD_SERVICE);
|
||||
imm.showSoftInput(mRangeEditText, 0);
|
||||
imm.showSoftInput(mPageRangeEditText, 0);
|
||||
}
|
||||
} else {
|
||||
mRangeEditText.setEnabled(false);
|
||||
mRangeEditText.setVisibility(View.INVISIBLE);
|
||||
mPageRangeEditText.setEnabled(false);
|
||||
mPageRangeEditText.setVisibility(View.INVISIBLE);
|
||||
mPageRangeTitle.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
final int pageCount = mDocument.info.getPageCount();
|
||||
mRangeTitle.setText(getString(R.string.label_pages,
|
||||
mRangeOptionsTitle.setText(getString(R.string.label_pages,
|
||||
(pageCount == PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
|
||||
? getString(R.string.page_count_unknown)
|
||||
: String.valueOf(pageCount)));
|
||||
@@ -1642,16 +1677,29 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mRangeOptionsSpinner.setSelection(0);
|
||||
}
|
||||
mRangeOptionsSpinner.setEnabled(false);
|
||||
mRangeTitle.setText(getString(R.string.label_pages,
|
||||
mRangeOptionsTitle.setText(getString(R.string.label_pages,
|
||||
getString(R.string.page_count_unknown)));
|
||||
mRangeEditText.setEnabled(false);
|
||||
mRangeEditText.setVisibility(View.INVISIBLE);
|
||||
mPageRangeEditText.setEnabled(false);
|
||||
mPageRangeEditText.setVisibility(View.INVISIBLE);
|
||||
mPageRangeTitle.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
mRangeOptionsSpinner.setEnabled(true);
|
||||
|
||||
// Print/Print preview
|
||||
if (mDestinationSpinner.getSelectedItemId()
|
||||
!= DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF) {
|
||||
String newText = getString(R.string.print_button);
|
||||
if (!TextUtils.equals(newText, mPrintButton.getText())) {
|
||||
mPrintButton.setText(R.string.print_button);
|
||||
}
|
||||
} else {
|
||||
String newText = getString(R.string.save_button);
|
||||
if (!TextUtils.equals(newText, mPrintButton.getText())) {
|
||||
mPrintButton.setText(R.string.save_button);
|
||||
}
|
||||
}
|
||||
if ((mRangeOptionsSpinner.getSelectedItemPosition() == 1
|
||||
&& (TextUtils.isEmpty(mRangeEditText.getText()) || hasErrors()))
|
||||
&& (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors()))
|
||||
|| (mRangeOptionsSpinner.getSelectedItemPosition() == 0
|
||||
&& (!mController.hasPerformedLayout() || hasErrors()))) {
|
||||
// mPrintPreviewButton.setEnabled(false);
|
||||
@@ -1667,6 +1715,12 @@ public class PrintJobConfigActivity extends Activity {
|
||||
}
|
||||
|
||||
// Copies
|
||||
if (mDestinationSpinner.getSelectedItemId()
|
||||
!= DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF) {
|
||||
mCopiesEditText.setEnabled(true);
|
||||
} else {
|
||||
mCopiesEditText.setEnabled(false);
|
||||
}
|
||||
if (mCopiesEditText.getError() == null
|
||||
&& TextUtils.isEmpty(mCopiesEditText.getText())) {
|
||||
mIgnoreNextCopiesChange = true;
|
||||
@@ -1674,13 +1728,62 @@ public class PrintJobConfigActivity extends Activity {
|
||||
mCopiesEditText.selectAll();
|
||||
mCopiesEditText.requestFocus();
|
||||
}
|
||||
mCopiesEditText.setEnabled(true);
|
||||
|
||||
return someAttributeSelectionChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setMediaSizeSpinnerSelectionNoCallback(int position) {
|
||||
if (mMediaSizeSpinner.getSelectedItemPosition() != position) {
|
||||
mIgnoreNextMediaSizeChange = true;
|
||||
mMediaSizeSpinner.setSelection(position);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateUiForNewPrinterCapabilities() {
|
||||
// The printer changed so we want to start with a clean slate
|
||||
// for the print options and let them be populated from the
|
||||
// printer capabilities and use the printer defaults.
|
||||
if (!mMediaSizeSpinnerAdapter.isEmpty()) {
|
||||
mIgnoreNextMediaSizeChange = true;
|
||||
mMediaSizeSpinnerAdapter.clear();
|
||||
}
|
||||
if (!mColorModeSpinnerAdapter.isEmpty()) {
|
||||
mIgnoreNextColorModeChange = true;
|
||||
mColorModeSpinnerAdapter.clear();
|
||||
}
|
||||
if (!mOrientationSpinnerAdapter.isEmpty()) {
|
||||
mIgnoreNextOrientationChange = true;
|
||||
mOrientationSpinnerAdapter.clear();
|
||||
}
|
||||
if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
|
||||
mIgnoreNextRangeOptionChange = true;
|
||||
mRangeOptionsSpinner.setSelection(0);
|
||||
}
|
||||
if (!TextUtils.isEmpty(mCopiesEditText.getText())) {
|
||||
mIgnoreNextCopiesChange = true;
|
||||
mCopiesEditText.setText(MIN_COPIES_STRING);
|
||||
}
|
||||
|
||||
updateUi();
|
||||
}
|
||||
|
||||
private void startSelectPrinterActivity() {
|
||||
mIgnoreNextDestinationChange = true;
|
||||
mDestinationSpinner.setSelection(0);
|
||||
Intent intent = new Intent(PrintJobConfigActivity.this,
|
||||
SelectPrinterActivity.class);
|
||||
startActivityForResult(intent, ACTIVITY_REQUEST_SELECT_PRINTER);
|
||||
}
|
||||
|
||||
private boolean hasErrors() {
|
||||
return mRangeEditText.getError() != null
|
||||
|| mCopiesEditText.getError() != null;
|
||||
if (mCopiesEditText.getError() != null) {
|
||||
return true;
|
||||
}
|
||||
return mPageRangeEditText.getVisibility() == View.VISIBLE
|
||||
&& mPageRangeEditText.getError() != null;
|
||||
}
|
||||
|
||||
// private boolean hasPdfViewer() {
|
||||
@@ -1708,29 +1811,49 @@ public class PrintJobConfigActivity extends Activity {
|
||||
implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>{
|
||||
private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>();
|
||||
|
||||
public final PrinterInfo mFakePdfPrinter;
|
||||
private final PrinterInfo mFakePdfPrinter;
|
||||
|
||||
private PrinterId mLastShownPrinterId;
|
||||
|
||||
public DestinationAdapter() {
|
||||
getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, null, this);
|
||||
mFakePdfPrinter = createFakePdfPrinter();
|
||||
}
|
||||
|
||||
public int getPrinterIndex(PrinterId printerId) {
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
PrinterInfo printer = (PrinterInfo) getItem(i);
|
||||
if (printer != null && printer.getId().equals(printerId)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return AdapterView.INVALID_POSITION;
|
||||
}
|
||||
|
||||
public void ensurePrinterShownPrinterShown(PrinterId printerId) {
|
||||
mLastShownPrinterId = printerId;
|
||||
ensureLastShownPrinterInPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return Math.max(Math.min(mPrinters.size(), DEST_ADAPTER_MAX_ITEM_COUNT),
|
||||
DEST_ADAPTER_MIN_ITEM_COUNT);
|
||||
return Math.min(mPrinters.size() + 2, DEST_ADAPTER_MAX_ITEM_COUNT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
if (position == DEST_ADAPTER_POSITION_SAVE_AS_PDF) {
|
||||
return mFakePdfPrinter;
|
||||
}
|
||||
if (!mPrinters.isEmpty()) {
|
||||
if (position < DEST_ADAPTER_POSITION_SAVE_AS_PDF) {
|
||||
if (mPrinters.isEmpty()) {
|
||||
if (position == 0) {
|
||||
return mFakePdfPrinter;
|
||||
}
|
||||
} else {
|
||||
if (position < 1) {
|
||||
return mPrinters.get(position);
|
||||
} else if (position > DEST_ADAPTER_POSITION_SAVE_AS_PDF
|
||||
&& position < getCount() - 1) {
|
||||
}
|
||||
if (position == 1) {
|
||||
return mFakePdfPrinter;
|
||||
}
|
||||
if (position < getCount() - 1) {
|
||||
return mPrinters.get(position - 1);
|
||||
}
|
||||
}
|
||||
@@ -1739,15 +1862,17 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
if (position == DEST_ADAPTER_POSITION_SAVE_AS_PDF) {
|
||||
return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
|
||||
}
|
||||
if (mPrinters.isEmpty()) {
|
||||
if (position == DEST_ADAPTER_POSITION_SEARCHING_FOR_PRINTERS) {
|
||||
return DEST_ADAPTER_ITEM_ID_SEARCHING_FOR_PRINTERS;
|
||||
if (position == 0) {
|
||||
return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
|
||||
}
|
||||
} else {
|
||||
if (position == 1) {
|
||||
return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
|
||||
}
|
||||
if (position == getCount() - 1) {
|
||||
return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
|
||||
}
|
||||
} else if (position == getCount() - 1) {
|
||||
return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
@@ -1768,11 +1893,15 @@ public class PrintJobConfigActivity extends Activity {
|
||||
CharSequence title = null;
|
||||
CharSequence subtitle = null;
|
||||
|
||||
if (mPrinters.isEmpty()
|
||||
&& position == DEST_ADAPTER_POSITION_SEARCHING_FOR_PRINTERS) {
|
||||
title = getString(R.string.searching_for_printers);
|
||||
if (mPrinters.isEmpty()) {
|
||||
if (position == 0) {
|
||||
PrinterInfo printer = (PrinterInfo) getItem(position);
|
||||
title = printer.getName();
|
||||
} else if (position == 1) {
|
||||
title = getString(R.string.all_printers);
|
||||
}
|
||||
} else {
|
||||
if (position == DEST_ADAPTER_POSITION_SAVE_AS_PDF) {
|
||||
if (position == 1) {
|
||||
PrinterInfo printer = (PrinterInfo) getItem(position);
|
||||
title = printer.getName();
|
||||
} else if (position == getCount() - 1) {
|
||||
@@ -1818,6 +1947,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
List<PrinterInfo> printers) {
|
||||
mPrinters.clear();
|
||||
mPrinters.addAll(printers);
|
||||
ensureLastShownPrinterInPosition();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@@ -1827,6 +1957,27 @@ public class PrintJobConfigActivity extends Activity {
|
||||
notifyDataSetInvalidated();
|
||||
}
|
||||
|
||||
private void ensureLastShownPrinterInPosition() {
|
||||
if (mLastShownPrinterId == null) {
|
||||
return;
|
||||
}
|
||||
final int printerCount = mPrinters.size();
|
||||
for (int i = 0; i < printerCount; i++) {
|
||||
PrinterInfo printer = (PrinterInfo) mPrinters.get(i);
|
||||
if (printer.getId().equals(mLastShownPrinterId)) {
|
||||
// If already in the list - do nothing.
|
||||
if (i < getCount() - 1) {
|
||||
return;
|
||||
}
|
||||
// Else replace the last one.
|
||||
final int lastPrinter = getCount() - 2;
|
||||
mPrinters.set(i, mPrinters.get(lastPrinter - 1));
|
||||
mPrinters.set(lastPrinter - 1, printer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PrinterInfo createFakePdfPrinter() {
|
||||
PrinterId printerId = new PrinterId(getComponentName(), "PDF printer");
|
||||
|
||||
|
||||
@@ -103,8 +103,6 @@ public final class PrintSpoolerService extends Service {
|
||||
|
||||
private NotificationController mNotificationController;
|
||||
|
||||
private PrinterDiscoverySession mDiscoverySession;
|
||||
|
||||
public static PrintSpoolerService peekInstance() {
|
||||
synchronized (sLock) {
|
||||
return sInstance;
|
||||
@@ -225,61 +223,9 @@ public final class PrintSpoolerService extends Service {
|
||||
HandlerCallerCallback.MSG_SET_CLIENT, client);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersAdded(List<PrinterInfo> printers) {
|
||||
Message message = mHandlerCaller.obtainMessageO(
|
||||
HandlerCallerCallback.MSG_ON_PRINTERS_ADDED, printers);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersRemoved(List<PrinterId> printerIds) {
|
||||
Message message = mHandlerCaller.obtainMessageO(
|
||||
HandlerCallerCallback.MSG_ON_PRINTERS_REMOVED, printerIds);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersUpdated(List<PrinterInfo> printers) {
|
||||
Message message = mHandlerCaller.obtainMessageO(
|
||||
HandlerCallerCallback.MSG_ON_PRINTERS_UPDATED, printers);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void createPrinterDiscoverySession() {
|
||||
Message message = mHandlerCaller.obtainMessage(
|
||||
HandlerCallerCallback.MSG_CREATE_PRINTER_DISCOVERY_SESSION);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
|
||||
public void destroyPrinterDiscoverySession() {
|
||||
Message message = mHandlerCaller.obtainMessage(
|
||||
HandlerCallerCallback.MSG_DESTROY_PRINTER_DISCOVERY_SESSION);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
|
||||
public void startPrinterDiscovery(List<PrinterId> priorityList) {
|
||||
Message message = mHandlerCaller.obtainMessageO(
|
||||
HandlerCallerCallback.MSG_START_PRINTER_DISCOVERY, priorityList);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
|
||||
public void stopPrinterDiscovery() {
|
||||
Message message = mHandlerCaller.obtainMessage(
|
||||
HandlerCallerCallback.MSG_STOP_PRINTER_DISCOVERY);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
|
||||
public void requestPrinterUpdate(PrinterId pritnerId) {
|
||||
Message message = mHandlerCaller.obtainMessageO(
|
||||
HandlerCallerCallback.MSG_REQUEST_PRINTER_UPDATE, pritnerId);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
|
||||
|
||||
private void sendOnPrintJobQueued(PrintJobInfo printJob) {
|
||||
Message message = mHandlerCaller.obtainMessageO(
|
||||
HandlerCallerCallback.MSG_ON_PRINT_JOB_QUEUED, printJob);
|
||||
@@ -299,16 +245,6 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
|
||||
private final class HandlerCallerCallback implements HandlerCaller.Callback {
|
||||
public static final int MSG_CREATE_PRINTER_DISCOVERY_SESSION = 1;
|
||||
public static final int MSG_DESTROY_PRINTER_DISCOVERY_SESSION = 2;
|
||||
public static final int MSG_START_PRINTER_DISCOVERY = 3;
|
||||
public static final int MSG_STOP_PRINTER_DISCOVERY = 4;
|
||||
public static final int MSG_REQUEST_PRINTER_UPDATE = 5;
|
||||
|
||||
public static final int MSG_ON_PRINTERS_ADDED = 6;
|
||||
public static final int MSG_ON_PRINTERS_REMOVED = 7;
|
||||
public static final int MSG_ON_PRINTERS_UPDATED = 8;
|
||||
|
||||
public static final int MSG_SET_CLIENT = 9;
|
||||
public static final int MSG_START_PRINT_JOB_CONFIG_ACTIVITY = 10;
|
||||
public static final int MSG_ON_PRINT_JOB_QUEUED = 11;
|
||||
@@ -317,81 +253,8 @@ public final class PrintSpoolerService extends Service {
|
||||
public static final int MSG_CHECK_ALL_PRINTJOBS_HANDLED = 14;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void executeMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case MSG_CREATE_PRINTER_DISCOVERY_SESSION: {
|
||||
final IPrintSpoolerClient client;
|
||||
synchronized (mLock) {
|
||||
client = mClient;
|
||||
}
|
||||
if (client != null) {
|
||||
try {
|
||||
client.createPrinterDiscoverySession();
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error creating printer discovery session.", re);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case MSG_DESTROY_PRINTER_DISCOVERY_SESSION: {
|
||||
final IPrintSpoolerClient client;
|
||||
synchronized (mLock) {
|
||||
client = mClient;
|
||||
}
|
||||
if (client != null) {
|
||||
try {
|
||||
client.destroyPrinterDiscoverySession();
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error destroying printer discovery session.", re);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case MSG_START_PRINTER_DISCOVERY: {
|
||||
final IPrintSpoolerClient client;
|
||||
synchronized (mLock) {
|
||||
client = mClient;
|
||||
}
|
||||
if (client != null) {
|
||||
List<PrinterId> priorityList = (ArrayList<PrinterId>) message.obj;
|
||||
try {
|
||||
client.startPrinterDiscovery(priorityList);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error starting printer discovery.", re);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case MSG_STOP_PRINTER_DISCOVERY: {
|
||||
final IPrintSpoolerClient client;
|
||||
synchronized (mLock) {
|
||||
client = mClient;
|
||||
}
|
||||
if (client != null) {
|
||||
try {
|
||||
client.stopPrinterDiscovery();
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error stopping printer discovery.", re);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case MSG_REQUEST_PRINTER_UPDATE: {
|
||||
final IPrintSpoolerClient client;
|
||||
synchronized (mLock) {
|
||||
client = mClient;
|
||||
}
|
||||
if (client != null) {
|
||||
PrinterId printerId = (PrinterId) message.obj;
|
||||
try {
|
||||
client.requestPrinterUpdate(printerId);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error requesing printer update.", re);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case MSG_SET_CLIENT: {
|
||||
synchronized (mLock) {
|
||||
mClient = (IPrintSpoolerClient) message.obj;
|
||||
@@ -452,39 +315,6 @@ public final class PrintSpoolerService extends Service {
|
||||
case MSG_CHECK_ALL_PRINTJOBS_HANDLED: {
|
||||
checkAllPrintJobsHandled();
|
||||
} break;
|
||||
|
||||
case MSG_ON_PRINTERS_ADDED: {
|
||||
final PrinterDiscoverySession session;
|
||||
synchronized (mLock) {
|
||||
session = mDiscoverySession;
|
||||
}
|
||||
if (session != null) {
|
||||
List<PrinterInfo> printers = (ArrayList<PrinterInfo>) message.obj;
|
||||
session.onPrintersAdded(printers);
|
||||
}
|
||||
} break;
|
||||
|
||||
case MSG_ON_PRINTERS_REMOVED: {
|
||||
final PrinterDiscoverySession session;
|
||||
synchronized (mLock) {
|
||||
session = mDiscoverySession;
|
||||
}
|
||||
if (session != null) {
|
||||
List<PrinterId> printerIds = (ArrayList<PrinterId>) message.obj;
|
||||
session.onPrintersRemoved(printerIds);
|
||||
}
|
||||
} break;
|
||||
|
||||
case MSG_ON_PRINTERS_UPDATED: {
|
||||
final PrinterDiscoverySession session;
|
||||
synchronized (mLock) {
|
||||
session = mDiscoverySession;
|
||||
}
|
||||
if (session != null) {
|
||||
List<PrinterInfo> printers = (ArrayList<PrinterInfo>) message.obj;
|
||||
session.onPrintersUpdated(printers);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -583,12 +413,6 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private void setPrinterDiscoverySessionClient(PrinterDiscoverySession session) {
|
||||
synchronized (mLock) {
|
||||
mDiscoverySession = session;
|
||||
}
|
||||
}
|
||||
|
||||
private int generatePrintJobIdLocked() {
|
||||
int printJobId = sPrintJobIdCounter++;
|
||||
while (isDuplicatePrintJobId(printJobId)) {
|
||||
@@ -1352,46 +1176,4 @@ public final class PrintSpoolerService extends Service {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class PrinterDiscoverySession {
|
||||
|
||||
private PrintSpoolerService mService;
|
||||
|
||||
private boolean mIsStarted;
|
||||
|
||||
public PrinterDiscoverySession() {
|
||||
mService = PrintSpoolerService.peekInstance();
|
||||
mService.createPrinterDiscoverySession();
|
||||
mService.setPrinterDiscoverySessionClient(this);
|
||||
}
|
||||
|
||||
public final void startPrinterDisovery(List<PrinterId> priorityList) {
|
||||
mIsStarted = true;
|
||||
mService.startPrinterDiscovery(priorityList);
|
||||
}
|
||||
|
||||
public final void stopPrinterDiscovery() {
|
||||
mIsStarted = false;
|
||||
mService.stopPrinterDiscovery();
|
||||
}
|
||||
|
||||
public void requestPrinterUpdated(PrinterId printerId) {
|
||||
mService.requestPrinterUpdate(printerId);
|
||||
}
|
||||
|
||||
public final void destroy() {
|
||||
mService.setPrinterDiscoverySessionClient(null);
|
||||
mService.destroyPrinterDiscoverySession();
|
||||
}
|
||||
|
||||
public final boolean isStarted() {
|
||||
return mIsStarted;
|
||||
}
|
||||
|
||||
public abstract void onPrintersAdded(List<PrinterInfo> printers);
|
||||
|
||||
public abstract void onPrintersRemoved(List<PrinterId> printerIds);
|
||||
|
||||
public abstract void onPrintersUpdated(List<PrinterInfo> printers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,10 @@ import android.os.UserHandle;
|
||||
import android.print.IPrintClient;
|
||||
import android.print.IPrintDocumentAdapter;
|
||||
import android.print.IPrintManager;
|
||||
import android.print.IPrinterDiscoveryObserver;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrinterId;
|
||||
import android.provider.Settings;
|
||||
import android.util.SparseArray;
|
||||
|
||||
@@ -188,6 +190,84 @@ public final class PrintManagerService extends IPrintManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
|
||||
int userId) {
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final UserState userState;
|
||||
synchronized (mLock) {
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
userState.createPrinterDiscoverySession(observer);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
|
||||
int userId) {
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final UserState userState;
|
||||
synchronized (mLock) {
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
userState.destroyPrinterDiscoverySession(observer);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrinterDiscovery(IPrinterDiscoveryObserver observer,
|
||||
List<PrinterId> priorityList, int userId) {
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final UserState userState;
|
||||
synchronized (mLock) {
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
userState.startPrinterDiscovery(observer, priorityList);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) {
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final UserState userState;
|
||||
synchronized (mLock) {
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
userState.stopPrinterDiscovery(observer);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestPrinterUpdate(PrinterId printerId, int userId) {
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final UserState userState;
|
||||
synchronized (mLock) {
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
userState.requestPrinterUpdate(printerId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerContentObservers() {
|
||||
final Uri enabledPrintServicesUri = Settings.Secure.getUriFor(
|
||||
Settings.Secure.ENABLED_PRINT_SERVICES);
|
||||
|
||||
@@ -61,6 +61,8 @@ final class RemotePrintService implements DeathRecipient {
|
||||
|
||||
private final RemotePrintSpooler mSpooler;
|
||||
|
||||
private final UserState mUserState;
|
||||
|
||||
private final int mUserId;
|
||||
|
||||
private final List<Runnable> mPendingCommands = new ArrayList<Runnable>();
|
||||
@@ -82,8 +84,9 @@ final class RemotePrintService implements DeathRecipient {
|
||||
private boolean mHasPrinterDiscoverySession;
|
||||
|
||||
public RemotePrintService(Context context, ComponentName componentName, int userId,
|
||||
RemotePrintSpooler spooler) {
|
||||
RemotePrintSpooler spooler, UserState userState) {
|
||||
mContext = context;
|
||||
mUserState = userState;
|
||||
mComponentName = componentName;
|
||||
mIntent = new Intent().setComponent(mComponentName);
|
||||
mUserId = userId;
|
||||
@@ -561,7 +564,7 @@ final class RemotePrintService implements DeathRecipient {
|
||||
throwIfPrinterIdsForPrinterInfoTampered(service.mComponentName, printers);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
service.mSpooler.onPrintersAdded(printers);
|
||||
service.mUserState.onPrintersAdded(printers);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
@@ -575,7 +578,7 @@ final class RemotePrintService implements DeathRecipient {
|
||||
throwIfPrinterIdsTampered(service.mComponentName, printerIds);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
service.mSpooler.onPrintersRemoved(printerIds);
|
||||
service.mUserState.onPrintersRemoved(printerIds);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
@@ -589,7 +592,7 @@ final class RemotePrintService implements DeathRecipient {
|
||||
throwIfPrinterIdsForPrinterInfoTampered(service.mComponentName, printers);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
service.mSpooler.onPrintersUpdated(printers);
|
||||
service.mUserState.onPrintersUpdated(printers);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ import android.print.IPrintSpoolerCallbacks;
|
||||
import android.print.IPrintSpoolerClient;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrinterInfo;
|
||||
import android.util.Slog;
|
||||
import android.util.TimedRemoteCaller;
|
||||
|
||||
@@ -93,11 +91,6 @@ final class RemotePrintSpooler {
|
||||
public static interface PrintSpoolerCallbacks {
|
||||
public void onPrintJobQueued(PrintJobInfo printJob);
|
||||
public void onAllPrintJobsForServiceHandled(ComponentName printService);
|
||||
public void createPrinterDiscoverySession();
|
||||
public void destroyPrinterDiscoverySession();
|
||||
public void startPrinterDiscovery(List<PrinterId> priorityList);
|
||||
public void stopPrinterDiscovery();
|
||||
public void requestPrinterUpdate(PrinterId printerId);
|
||||
}
|
||||
|
||||
public RemotePrintSpooler(Context context, int userId,
|
||||
@@ -305,78 +298,6 @@ final class RemotePrintSpooler {
|
||||
}
|
||||
}
|
||||
|
||||
public final void onPrintersAdded(List<PrinterInfo> printers) {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
mCanUnbind = false;
|
||||
}
|
||||
try {
|
||||
getRemoteInstanceLazy().onPrintersAdded(printers);
|
||||
} catch (RemoteException re) {
|
||||
Slog.e(LOG_TAG, "Error adding printers.", re);
|
||||
} catch (TimeoutException te) {
|
||||
Slog.e(LOG_TAG, "Error adding printers.", te);
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
|
||||
+ "] onPrintersAdded()");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
mCanUnbind = true;
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void onPrintersRemoved(List<PrinterId> printerIds) {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
mCanUnbind = false;
|
||||
}
|
||||
try {
|
||||
getRemoteInstanceLazy().onPrintersRemoved(printerIds);
|
||||
} catch (RemoteException re) {
|
||||
Slog.e(LOG_TAG, "Error removing printers.", re);
|
||||
} catch (TimeoutException te) {
|
||||
Slog.e(LOG_TAG, "Error removing printers.", te);
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
|
||||
+ "] onPrintersRemoved()");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
mCanUnbind = true;
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void onPrintersUpdated(List<PrinterInfo> printers) {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
mCanUnbind = false;
|
||||
}
|
||||
try {
|
||||
getRemoteInstanceLazy().onPrintersUpdated(printers);
|
||||
} catch (RemoteException re) {
|
||||
Slog.e(LOG_TAG, "Error updating printers.", re);
|
||||
} catch (TimeoutException te) {
|
||||
Slog.e(LOG_TAG, "Error updating printers.", te);
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
|
||||
+ "] onPrintersUpdted()");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
mCanUnbind = true;
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException {
|
||||
synchronized (mLock) {
|
||||
if (mRemoteInstance != null) {
|
||||
@@ -672,70 +593,5 @@ final class RemotePrintSpooler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPrinterDiscoverySession() {
|
||||
RemotePrintSpooler spooler = mWeakSpooler.get();
|
||||
if (spooler != null) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
spooler.mCallbacks.createPrinterDiscoverySession();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyPrinterDiscoverySession() {
|
||||
RemotePrintSpooler spooler = mWeakSpooler.get();
|
||||
if (spooler != null) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
spooler.mCallbacks.destroyPrinterDiscoverySession();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrinterDiscovery(List<PrinterId> priorityList) {
|
||||
RemotePrintSpooler spooler = mWeakSpooler.get();
|
||||
if (spooler != null) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
spooler.mCallbacks.startPrinterDiscovery(priorityList);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopPrinterDiscovery() {
|
||||
RemotePrintSpooler spooler = mWeakSpooler.get();
|
||||
if (spooler != null) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
spooler.mCallbacks.stopPrinterDiscovery();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestPrinterUpdate(PrinterId printerId) {
|
||||
RemotePrintSpooler spooler = mWeakSpooler.get();
|
||||
if (spooler != null) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
spooler.mCallbacks.requestPrinterUpdate(printerId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,26 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.print.IPrinterDiscoveryObserver;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrinterInfo;
|
||||
import android.printservice.PrintServiceInfo;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextUtils.SimpleStringSplitter;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.server.print.RemotePrintSpooler.PrintSpoolerCallbacks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -45,6 +57,10 @@ final class UserState implements PrintSpoolerCallbacks {
|
||||
|
||||
private static final String LOG_TAG = "UserState";
|
||||
|
||||
private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
|
||||
|
||||
private static final int MAX_ITEMS_PER_CALLBACK = 100;
|
||||
|
||||
private static final char COMPONENT_NAME_SEPARATOR = ':';
|
||||
|
||||
private final SimpleStringSplitter mStringColonSplitter =
|
||||
@@ -70,6 +86,8 @@ final class UserState implements PrintSpoolerCallbacks {
|
||||
|
||||
private final RemotePrintSpooler mSpooler;
|
||||
|
||||
private PrinterDiscoverySessionMediator mPrinterDiscoverySession;
|
||||
|
||||
private boolean mDestroyed;
|
||||
|
||||
public UserState(Context context, int userId, Object lock) {
|
||||
@@ -104,86 +122,135 @@ final class UserState implements PrintSpoolerCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPrinterDiscoverySession() {
|
||||
final List<RemotePrintService> services;
|
||||
public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer) {
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
if (mActiveServices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
services = new ArrayList<RemotePrintService>(mActiveServices.values());
|
||||
}
|
||||
final int serviceCount = services.size();
|
||||
for (int i = 0; i < serviceCount; i++) {
|
||||
RemotePrintService service = services.get(i);
|
||||
service.createPrinterDiscoverySession();
|
||||
if (mPrinterDiscoverySession == null) {
|
||||
// If we do not have a session, tell all service to create one.
|
||||
mPrinterDiscoverySession = new PrinterDiscoverySessionMediator(mContext) {
|
||||
@Override
|
||||
public void onDestroyed() {
|
||||
mPrinterDiscoverySession = null;
|
||||
}
|
||||
};
|
||||
// Add the observer to the brand new session.
|
||||
mPrinterDiscoverySession.addObserverLocked(observer);
|
||||
} else {
|
||||
// If services have created session, just add the observer.
|
||||
mPrinterDiscoverySession.addObserverLocked(observer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyPrinterDiscoverySession() {
|
||||
final List<RemotePrintService> services;
|
||||
public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer) {
|
||||
synchronized (mLock) {
|
||||
// Already destroyed - nothing to do.
|
||||
if (mPrinterDiscoverySession == null) {
|
||||
return;
|
||||
}
|
||||
// Remove this observer.
|
||||
mPrinterDiscoverySession.removeObserverLocked(observer);
|
||||
}
|
||||
}
|
||||
|
||||
public void startPrinterDiscovery(IPrinterDiscoveryObserver observer,
|
||||
List<PrinterId> printerIds) {
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
// No services - nothing to do.
|
||||
if (mActiveServices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
services = new ArrayList<RemotePrintService>(mActiveServices.values());
|
||||
}
|
||||
final int serviceCount = services.size();
|
||||
for (int i = 0; i < serviceCount; i++) {
|
||||
RemotePrintService service = services.get(i);
|
||||
service.destroyPrinterDiscoverySession();
|
||||
// No session - nothing to do.
|
||||
if (mPrinterDiscoverySession == null) {
|
||||
return;
|
||||
}
|
||||
// Kick of discovery.
|
||||
mPrinterDiscoverySession.startPrinterDiscoveryLocked(observer,
|
||||
printerIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrinterDiscovery(List<PrinterId> printerIds) {
|
||||
final List<RemotePrintService> services;
|
||||
public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer) {
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
// No services - nothing to do.
|
||||
if (mActiveServices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
services = new ArrayList<RemotePrintService>(mActiveServices.values());
|
||||
}
|
||||
final int serviceCount = services.size();
|
||||
for (int i = 0; i < serviceCount; i++) {
|
||||
RemotePrintService service = services.get(i);
|
||||
service.startPrinterDiscovery(printerIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopPrinterDiscovery() {
|
||||
final List<RemotePrintService> services;
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
if (mActiveServices.isEmpty()) {
|
||||
// No session - nothing to do.
|
||||
if (mPrinterDiscoverySession == null) {
|
||||
return;
|
||||
}
|
||||
services = new ArrayList<RemotePrintService>(mActiveServices.values());
|
||||
}
|
||||
final int serviceCount = services.size();
|
||||
for (int i = 0; i < serviceCount; i++) {
|
||||
RemotePrintService service = services.get(i);
|
||||
service.stopPrinterDiscovery();
|
||||
// Kick of discovery.
|
||||
mPrinterDiscoverySession.stopPrinterDiscoveryLocked(observer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestPrinterUpdate(PrinterId printerId) {
|
||||
final RemotePrintService service;
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
// No services - nothing to do.
|
||||
if (mActiveServices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
service = mActiveServices.get(printerId.getServiceName());
|
||||
// No session - nothing to do.
|
||||
if (mPrinterDiscoverySession == null) {
|
||||
return;
|
||||
}
|
||||
// Request an updated.
|
||||
mPrinterDiscoverySession.requestPrinterUpdateLocked(printerId);
|
||||
}
|
||||
if (service != null) {
|
||||
service.requestPrinterUpdate(printerId);
|
||||
}
|
||||
|
||||
public void onPrintersAdded(List<PrinterInfo> printers) {
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
// No services - nothing to do.
|
||||
if (mActiveServices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// No session - nothing to do.
|
||||
if (mPrinterDiscoverySession == null) {
|
||||
return;
|
||||
}
|
||||
// Request an updated.
|
||||
mPrinterDiscoverySession.onPrintersAddedLocked(printers);
|
||||
}
|
||||
}
|
||||
|
||||
public void onPrintersRemoved(List<PrinterId> printerIds) {
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
// No services - nothing to do.
|
||||
if (mActiveServices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// No session - nothing to do.
|
||||
if (mPrinterDiscoverySession == null) {
|
||||
return;
|
||||
}
|
||||
// Request an updated.
|
||||
mPrinterDiscoverySession.onPrintersRemovedLocked(printerIds);
|
||||
}
|
||||
}
|
||||
|
||||
public void onPrintersUpdated(List<PrinterInfo> printers) {
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
// No services - nothing to do.
|
||||
if (mActiveServices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// No session - nothing to do.
|
||||
if (mPrinterDiscoverySession == null) {
|
||||
return;
|
||||
}
|
||||
// Request an updated.
|
||||
mPrinterDiscoverySession.onPrintersUpdatedLocked(printers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +289,10 @@ final class UserState implements PrintSpoolerCallbacks {
|
||||
mActiveServices.clear();
|
||||
mInstalledServices.clear();
|
||||
mEnabledServices.clear();
|
||||
if (mPrinterDiscoverySession != null) {
|
||||
mPrinterDiscoverySession.destroyLocked();
|
||||
mPrinterDiscoverySession = null;
|
||||
}
|
||||
mDestroyed = true;
|
||||
}
|
||||
|
||||
@@ -302,13 +373,20 @@ final class UserState implements PrintSpoolerCallbacks {
|
||||
resolveInfo.serviceInfo.name);
|
||||
if (mEnabledServices.contains(serviceName)) {
|
||||
if (!mActiveServices.containsKey(serviceName)) {
|
||||
mActiveServices.put(serviceName, new RemotePrintService(
|
||||
mContext, serviceName, mUserId, mSpooler));
|
||||
RemotePrintService service = new RemotePrintService(
|
||||
mContext, serviceName, mUserId, mSpooler, this);
|
||||
mActiveServices.put(serviceName, service);
|
||||
if (mPrinterDiscoverySession != null) {
|
||||
mPrinterDiscoverySession.onServiceAddedLocked(service);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RemotePrintService service = mActiveServices.remove(serviceName);
|
||||
if (service != null) {
|
||||
service.destroy();
|
||||
if (mPrinterDiscoverySession != null) {
|
||||
mPrinterDiscoverySession.onServiceRemovedLocked(serviceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,5 +397,496 @@ final class UserState implements PrintSpoolerCallbacks {
|
||||
throw new IllegalStateException("Cannot interact with a destroyed instance.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PrinterDiscoverySessionMediator {
|
||||
private final ArrayMap<PrinterId, PrinterInfo> mPrinters =
|
||||
new ArrayMap<PrinterId, PrinterInfo>();
|
||||
|
||||
private final RemoteCallbackList<IPrinterDiscoveryObserver> mDiscoveryObservers =
|
||||
new RemoteCallbackList<IPrinterDiscoveryObserver>() {
|
||||
@Override
|
||||
public void onCallbackDied(IPrinterDiscoveryObserver observer) {
|
||||
synchronized (mLock) {
|
||||
stopPrinterDiscoveryLocked(observer);
|
||||
removeObserverLocked(observer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final List<IBinder> mStartedPrinterDiscoveryTokens = new ArrayList<IBinder>();
|
||||
|
||||
private final Handler mHandler;
|
||||
|
||||
private boolean mIsDestroyed;
|
||||
|
||||
public PrinterDiscoverySessionMediator(Context context) {
|
||||
mHandler = new SessionHandler(context.getMainLooper());
|
||||
// Kick off the session creation.
|
||||
List<RemotePrintService> services = new ArrayList<RemotePrintService>(
|
||||
mActiveServices.values());
|
||||
mHandler.obtainMessage(SessionHandler
|
||||
.MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION, services)
|
||||
.sendToTarget();
|
||||
}
|
||||
|
||||
public void addObserverLocked(IPrinterDiscoveryObserver observer) {
|
||||
// Add the observer.
|
||||
mDiscoveryObservers.register(observer);
|
||||
|
||||
// Bring the added observer up to speed with the printers.
|
||||
if (!mPrinters.isEmpty()) {
|
||||
List<PrinterInfo> printers = new ArrayList<PrinterInfo>(mPrinters.values());
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = observer;
|
||||
args.arg2 = printers;
|
||||
mHandler.obtainMessage(SessionHandler.MSG_PRINTERS_ADDED,
|
||||
args).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeObserverLocked(IPrinterDiscoveryObserver observer) {
|
||||
// Remove the observer.
|
||||
mDiscoveryObservers.unregister(observer);
|
||||
// No one else observing - then kill it.
|
||||
if (mDiscoveryObservers.getRegisteredCallbackCount() == 0) {
|
||||
destroyLocked();
|
||||
}
|
||||
}
|
||||
|
||||
public final void startPrinterDiscoveryLocked(IPrinterDiscoveryObserver observer,
|
||||
List<PrinterId> priorityList) {
|
||||
if (mIsDestroyed) {
|
||||
Log.w(LOG_TAG, "Not starting dicovery - session destroyed");
|
||||
return;
|
||||
}
|
||||
|
||||
// If printer discovery is ongoing and the start request has a list
|
||||
// of printer to be checked, then we just request refreshing each of
|
||||
// them rather making another start discovery request.
|
||||
if (!mStartedPrinterDiscoveryTokens.isEmpty()
|
||||
&& priorityList != null && !priorityList.isEmpty()) {
|
||||
final int priorityIdCount = priorityList.size();
|
||||
for (int i = 0; i < priorityIdCount; i++) {
|
||||
requestPrinterUpdate(priorityList.get(i));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Remember we got a start request to match with an end.
|
||||
mStartedPrinterDiscoveryTokens.add(observer.asBinder());
|
||||
// The service are already performing discovery - nothing to do.
|
||||
if (mStartedPrinterDiscoveryTokens.size() > 1) {
|
||||
return;
|
||||
}
|
||||
List<RemotePrintService> services = new ArrayList<RemotePrintService>(
|
||||
mActiveServices.values());
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = services;
|
||||
args.arg2 = priorityList;
|
||||
mHandler.obtainMessage(SessionHandler
|
||||
.MSG_DISPATCH_START_PRINTER_DISCOVERY, args)
|
||||
.sendToTarget();
|
||||
}
|
||||
|
||||
public final void stopPrinterDiscoveryLocked(IPrinterDiscoveryObserver observer) {
|
||||
if (mIsDestroyed) {
|
||||
Log.w(LOG_TAG, "Not stopping dicovery - session destroyed");
|
||||
return;
|
||||
}
|
||||
// This one did not make an active discovery request - nothing to do.
|
||||
if (!mStartedPrinterDiscoveryTokens.remove(observer.asBinder())) {
|
||||
return;
|
||||
}
|
||||
// There are other interested observers - do not stop discovery.
|
||||
if (!mStartedPrinterDiscoveryTokens.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<RemotePrintService> services = new ArrayList<RemotePrintService>(
|
||||
mActiveServices.values());
|
||||
mHandler.obtainMessage(SessionHandler
|
||||
.MSG_DISPATCH_STOP_PRINTER_DISCOVERY, services)
|
||||
.sendToTarget();
|
||||
}
|
||||
|
||||
public void requestPrinterUpdateLocked(PrinterId printerId) {
|
||||
if (mIsDestroyed) {
|
||||
Log.w(LOG_TAG, "Not updating pritner - session destroyed");
|
||||
return;
|
||||
}
|
||||
RemotePrintService service = mActiveServices.get(printerId.getServiceName());
|
||||
if (service != null) {
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = service;
|
||||
args.arg2 = printerId;
|
||||
mHandler.obtainMessage(SessionHandler
|
||||
.MSG_REQUEST_PRINTER_UPDATE, args)
|
||||
.sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
public void onDestroyed() {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
public void destroyLocked() {
|
||||
if (mIsDestroyed) {
|
||||
Log.w(LOG_TAG, "Not destroying - session destroyed");
|
||||
return;
|
||||
}
|
||||
// Make sure discovery is stopped.
|
||||
final int observerCount = mStartedPrinterDiscoveryTokens.size();
|
||||
for (int i = 0; i < observerCount; i++) {
|
||||
IBinder token = mStartedPrinterDiscoveryTokens.get(i);
|
||||
stopPrinterDiscoveryLocked(IPrinterDiscoveryObserver.Stub.asInterface(token));
|
||||
}
|
||||
// Tell the services we are done.
|
||||
List<RemotePrintService> services = new ArrayList<RemotePrintService>(
|
||||
mActiveServices.values());
|
||||
mHandler.obtainMessage(SessionHandler
|
||||
.MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION, services)
|
||||
.sendToTarget();
|
||||
}
|
||||
|
||||
public void onPrintersAddedLocked(List<PrinterInfo> printers) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onPrintersAddedLocked()");
|
||||
}
|
||||
if (mIsDestroyed) {
|
||||
Log.w(LOG_TAG, "Not adding printers - session destroyed");
|
||||
return;
|
||||
}
|
||||
List<PrinterInfo> addedPrinters = null;
|
||||
final int addedPrinterCount = printers.size();
|
||||
for (int i = 0; i < addedPrinterCount; i++) {
|
||||
PrinterInfo printer = printers.get(i);
|
||||
if (!mPrinters.containsKey(printer.getId())) {
|
||||
mPrinters.put(printer.getId(), printer);
|
||||
if (addedPrinters == null) {
|
||||
addedPrinters = new ArrayList<PrinterInfo>();
|
||||
}
|
||||
addedPrinters.add(printer);
|
||||
}
|
||||
}
|
||||
if (addedPrinters != null) {
|
||||
mHandler.obtainMessage(SessionHandler.MSG_DISPATCH_PRINTERS_ADDED,
|
||||
addedPrinters).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
public void onPrintersRemovedLocked(List<PrinterId> printerIds) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onPrintersRemovedLocked()");
|
||||
}
|
||||
if (mIsDestroyed) {
|
||||
Log.w(LOG_TAG, "Not removing printers - session destroyed");
|
||||
return;
|
||||
}
|
||||
List<PrinterId> removedPrinterIds = null;
|
||||
final int removedPrinterCount = printerIds.size();
|
||||
for (int i = 0; i < removedPrinterCount; i++) {
|
||||
PrinterId removedPrinterId = printerIds.get(i);
|
||||
if (mPrinters.remove(removedPrinterId) != null) {
|
||||
if (removedPrinterIds == null) {
|
||||
removedPrinterIds = new ArrayList<PrinterId>();
|
||||
}
|
||||
removedPrinterIds.add(removedPrinterId);
|
||||
}
|
||||
}
|
||||
if (removedPrinterIds != null) {
|
||||
mHandler.obtainMessage(SessionHandler.MSG_DISPATCH_PRINTERS_REMOVED,
|
||||
removedPrinterIds).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
public void onPrintersUpdatedLocked(List<PrinterInfo> printers) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onPrintersUpdatedLocked()");
|
||||
}
|
||||
if (mIsDestroyed) {
|
||||
Log.w(LOG_TAG, "Not updating printers - session destroyed");
|
||||
return;
|
||||
}
|
||||
List<PrinterInfo> updatedPrinters = null;
|
||||
final int updatedPrinterCount = printers.size();
|
||||
for (int i = 0; i < updatedPrinterCount; i++) {
|
||||
PrinterInfo updatedPrinter = printers.get(i);
|
||||
if (mPrinters.containsKey(updatedPrinter.getId())) {
|
||||
mPrinters.put(updatedPrinter.getId(), updatedPrinter);
|
||||
if (updatedPrinters == null) {
|
||||
updatedPrinters = new ArrayList<PrinterInfo>();
|
||||
}
|
||||
updatedPrinters.add(updatedPrinter);
|
||||
}
|
||||
}
|
||||
if (updatedPrinters != null) {
|
||||
mHandler.obtainMessage(SessionHandler.MSG_DISPATCH_PRINTERS_UPDATED,
|
||||
updatedPrinters).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceRemovedLocked(ComponentName serviceName) {
|
||||
if (mIsDestroyed) {
|
||||
Log.w(LOG_TAG, "Not updating removed service - session destroyed");
|
||||
return;
|
||||
}
|
||||
// No printers - nothing to do.
|
||||
if (mPrinters.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// Remove the printers for that service.
|
||||
List<PrinterInfo> removedPrinters = null;
|
||||
final int printerCount = mPrinters.size();
|
||||
for (int i = 0; i < printerCount; i++) {
|
||||
PrinterInfo printer = mPrinters.get(i);
|
||||
if (printer.getId().getServiceName().equals(serviceName)) {
|
||||
if (removedPrinters == null) {
|
||||
removedPrinters = new ArrayList<PrinterInfo>();
|
||||
}
|
||||
removedPrinters.add(printer);
|
||||
}
|
||||
}
|
||||
if (!removedPrinters.isEmpty()) {
|
||||
mHandler.obtainMessage(
|
||||
SessionHandler.MSG_DISPATCH_PRINTERS_REMOVED,
|
||||
removedPrinters).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceAddedLocked(RemotePrintService service) {
|
||||
if (mIsDestroyed) {
|
||||
Log.w(LOG_TAG, "Not updating added service - session destroyed");
|
||||
return;
|
||||
}
|
||||
// Tell the service to create a session.
|
||||
mHandler.obtainMessage(
|
||||
SessionHandler.MSG_CREATE_PRINTER_DISCOVERY_SESSION,
|
||||
service).sendToTarget();
|
||||
// If there are some observers that started discovery - tell the service.
|
||||
if (mDiscoveryObservers.getRegisteredCallbackCount() > 0) {
|
||||
mHandler.obtainMessage(
|
||||
SessionHandler.MSG_START_PRINTER_DISCOVERY,
|
||||
service).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDispatchPrintersAdded(List<PrinterInfo> addedPrinters) {
|
||||
final int observerCount = mDiscoveryObservers.beginBroadcast();
|
||||
for (int i = 0; i < observerCount; i++) {
|
||||
IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i);
|
||||
try {
|
||||
observer.onPrintersAdded(addedPrinters);
|
||||
} catch (RemoteException re) {
|
||||
Log.i(LOG_TAG, "Error dispatching added printers", re);
|
||||
}
|
||||
}
|
||||
mDiscoveryObservers.finishBroadcast();
|
||||
}
|
||||
|
||||
private void handleDispatchPrintersRemoved(List<PrinterId> removedPrinterIds) {
|
||||
final int observerCount = mDiscoveryObservers.beginBroadcast();
|
||||
for (int i = 0; i < observerCount; i++) {
|
||||
IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i);
|
||||
try {
|
||||
observer.onPrintersRemoved(removedPrinterIds);
|
||||
} catch (RemoteException re) {
|
||||
Log.i(LOG_TAG, "Error dispatching removed printers", re);
|
||||
}
|
||||
}
|
||||
mDiscoveryObservers.finishBroadcast();
|
||||
}
|
||||
|
||||
private void handleDispatchPrintersUpdated(List<PrinterInfo> updatedPrinters) {
|
||||
final int observerCount = mDiscoveryObservers.beginBroadcast();
|
||||
for (int i = 0; i < observerCount; i++) {
|
||||
IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i);
|
||||
try {
|
||||
observer.onPrintersUpdated(updatedPrinters);
|
||||
} catch (RemoteException re) {
|
||||
Log.i(LOG_TAG, "Error dispatching updated printers", re);
|
||||
}
|
||||
}
|
||||
mDiscoveryObservers.finishBroadcast();
|
||||
}
|
||||
|
||||
private void handleDispatchCreatePrinterDiscoverySession(
|
||||
List<RemotePrintService> services) {
|
||||
final int serviceCount = services.size();
|
||||
for (int i = 0; i < serviceCount; i++) {
|
||||
RemotePrintService service = services.get(i);
|
||||
service.createPrinterDiscoverySession();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDispatchDestroyPrinterDiscoverySession(
|
||||
List<RemotePrintService> services) {
|
||||
final int serviceCount = services.size();
|
||||
for (int i = 0; i < serviceCount; i++) {
|
||||
RemotePrintService service = services.get(i);
|
||||
service.destroyPrinterDiscoverySession();
|
||||
}
|
||||
onDestroyed();
|
||||
}
|
||||
|
||||
private void handleDispatchStartPrinterDiscovery(
|
||||
List<RemotePrintService> services, List<PrinterId> printerIds) {
|
||||
final int serviceCount = services.size();
|
||||
for (int i = 0; i < serviceCount; i++) {
|
||||
RemotePrintService service = services.get(i);
|
||||
service.startPrinterDiscovery(printerIds);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDispatchStopPrinterDiscovery(List<RemotePrintService> services) {
|
||||
final int serviceCount = services.size();
|
||||
for (int i = 0; i < serviceCount; i++) {
|
||||
RemotePrintService service = services.get(i);
|
||||
service.stopPrinterDiscovery();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRequestPrinterUpdate(RemotePrintService service,
|
||||
PrinterId printerId) {
|
||||
service.requestPrinterUpdate(printerId);
|
||||
}
|
||||
|
||||
private void handlePrintersAdded(IPrinterDiscoveryObserver observer,
|
||||
List<PrinterInfo> printers) {
|
||||
try {
|
||||
final int printerCount = printers.size();
|
||||
if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
|
||||
observer.onPrintersAdded(printers);
|
||||
} else {
|
||||
// Send the added printers in chunks avoiding the binder transaction limit.
|
||||
final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
|
||||
for (int i = 0; i < transactionCount; i++) {
|
||||
final int start = i * MAX_ITEMS_PER_CALLBACK;
|
||||
final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
|
||||
List<PrinterInfo> subPrinters = printers.subList(start, end);
|
||||
observer.onPrintersAdded(subPrinters);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending added printers", re);
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePrintersRemoved(IPrinterDiscoveryObserver observer,
|
||||
List<PrinterId> printerIds) {
|
||||
try {
|
||||
final int printerCount = printerIds.size();
|
||||
if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
|
||||
observer.onPrintersRemoved(printerIds);
|
||||
} else {
|
||||
// Send the added printers in chunks avoiding the binder transaction limit.
|
||||
final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
|
||||
for (int i = 0; i < transactionCount; i++) {
|
||||
final int start = i * MAX_ITEMS_PER_CALLBACK;
|
||||
final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
|
||||
List<PrinterId> subPrinterIds = printerIds.subList(start, end);
|
||||
observer.onPrintersRemoved(subPrinterIds);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending added printers", re);
|
||||
}
|
||||
}
|
||||
|
||||
private final class SessionHandler extends Handler {
|
||||
public static final int MSG_PRINTERS_ADDED = 1;
|
||||
public static final int MSG_PRINTERS_REMOVED = 2;
|
||||
public static final int MSG_DISPATCH_PRINTERS_ADDED = 3;
|
||||
public static final int MSG_DISPATCH_PRINTERS_REMOVED = 4;
|
||||
public static final int MSG_DISPATCH_PRINTERS_UPDATED = 5;
|
||||
|
||||
public static final int MSG_CREATE_PRINTER_DISCOVERY_SESSION = 6;
|
||||
public static final int MSG_START_PRINTER_DISCOVERY = 7;
|
||||
public static final int MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION = 8;
|
||||
public static final int MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION = 9;
|
||||
public static final int MSG_DISPATCH_START_PRINTER_DISCOVERY = 10;
|
||||
public static final int MSG_DISPATCH_STOP_PRINTER_DISCOVERY = 11;
|
||||
public static final int MSG_REQUEST_PRINTER_UPDATE = 12;
|
||||
|
||||
SessionHandler(Looper looper) {
|
||||
super(looper, null, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case MSG_PRINTERS_ADDED: {
|
||||
SomeArgs args = (SomeArgs) message.obj;
|
||||
IPrinterDiscoveryObserver observer = (IPrinterDiscoveryObserver) args.arg1;
|
||||
List<PrinterInfo> addedPrinters = (List<PrinterInfo>) args.arg2;
|
||||
args.recycle();
|
||||
handlePrintersAdded(observer, addedPrinters);
|
||||
} break;
|
||||
|
||||
case MSG_PRINTERS_REMOVED: {
|
||||
SomeArgs args = (SomeArgs) message.obj;
|
||||
IPrinterDiscoveryObserver observer = (IPrinterDiscoveryObserver) args.arg1;
|
||||
List<PrinterId> removedPrinterIds = (List<PrinterId>) args.arg2;
|
||||
args.recycle();
|
||||
handlePrintersRemoved(observer, removedPrinterIds);
|
||||
}
|
||||
|
||||
case MSG_DISPATCH_PRINTERS_ADDED: {
|
||||
List<PrinterInfo> addedPrinters = (List<PrinterInfo>) message.obj;
|
||||
handleDispatchPrintersAdded(addedPrinters);
|
||||
} break;
|
||||
|
||||
case MSG_DISPATCH_PRINTERS_REMOVED: {
|
||||
List<PrinterId> removedPrinterIds = (List<PrinterId>) message.obj;
|
||||
handleDispatchPrintersRemoved(removedPrinterIds);
|
||||
} break;
|
||||
|
||||
case MSG_DISPATCH_PRINTERS_UPDATED: {
|
||||
List<PrinterInfo> updatedPrinters = (List<PrinterInfo>) message.obj;
|
||||
handleDispatchPrintersUpdated(updatedPrinters);
|
||||
} break;
|
||||
|
||||
case MSG_CREATE_PRINTER_DISCOVERY_SESSION: {
|
||||
RemotePrintService service = (RemotePrintService) message.obj;
|
||||
service.createPrinterDiscoverySession();
|
||||
} break;
|
||||
|
||||
case MSG_START_PRINTER_DISCOVERY: {
|
||||
RemotePrintService service = (RemotePrintService) message.obj;
|
||||
service.startPrinterDiscovery(null);
|
||||
} break;
|
||||
|
||||
case MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION: {
|
||||
List<RemotePrintService> services = (List<RemotePrintService>) message.obj;
|
||||
handleDispatchCreatePrinterDiscoverySession(services);
|
||||
} break;
|
||||
|
||||
case MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION: {
|
||||
List<RemotePrintService> services = (List<RemotePrintService>) message.obj;
|
||||
handleDispatchDestroyPrinterDiscoverySession(services);
|
||||
} break;
|
||||
|
||||
case MSG_DISPATCH_START_PRINTER_DISCOVERY: {
|
||||
SomeArgs args = (SomeArgs) message.obj;
|
||||
List<RemotePrintService> services = (List<RemotePrintService>) args.arg1;
|
||||
List<PrinterId> printerIds = (List<PrinterId>) args.arg2;
|
||||
args.recycle();
|
||||
handleDispatchStartPrinterDiscovery(services, printerIds);
|
||||
} break;
|
||||
|
||||
case MSG_DISPATCH_STOP_PRINTER_DISCOVERY: {
|
||||
List<RemotePrintService> services = (List<RemotePrintService>) message.obj;
|
||||
handleDispatchStopPrinterDiscovery(services);
|
||||
} break;
|
||||
|
||||
case MSG_REQUEST_PRINTER_UPDATE: {
|
||||
SomeArgs args = (SomeArgs) message.obj;
|
||||
RemotePrintService service = (RemotePrintService) args.arg1;
|
||||
PrinterId printerId = (PrinterId) args.arg2;
|
||||
args.recycle();
|
||||
handleRequestPrinterUpdate(service, printerId);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user