diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/os/RemoteCallbackList.java | 2 | ||||
-rw-r--r-- | core/java/android/print/IPrintManager.aidl | 10 | ||||
-rw-r--r-- | core/java/android/print/IPrintSpooler.aidl | 6 | ||||
-rw-r--r-- | core/java/android/print/IPrintSpoolerClient.aidl | 8 | ||||
-rw-r--r-- | core/java/android/print/IPrinterDiscoveryObserver.aidl | 32 | ||||
-rw-r--r-- | core/java/android/print/PrintManager.java | 7 | ||||
-rw-r--r-- | core/java/android/print/PrinterDiscoverySession.java | 297 |
7 files changed, 346 insertions, 16 deletions
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java index c1d4ae9..d2a9cdc 100644 --- a/core/java/android/os/RemoteCallbackList.java +++ b/core/java/android/os/RemoteCallbackList.java @@ -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 diff --git a/core/java/android/print/IPrintManager.aidl b/core/java/android/print/IPrintManager.aidl index 7155096..3bfd9a1 100644 --- a/core/java/android/print/IPrintManager.aidl +++ b/core/java/android/print/IPrintManager.aidl @@ -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); } diff --git a/core/java/android/print/IPrintSpooler.aidl b/core/java/android/print/IPrintSpooler.aidl index 5c8a22a..0a77dab 100644 --- a/core/java/android/print/IPrintSpooler.aidl +++ b/core/java/android/print/IPrintSpooler.aidl @@ -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); } diff --git a/core/java/android/print/IPrintSpoolerClient.aidl b/core/java/android/print/IPrintSpoolerClient.aidl index da60120..8b511d6 100644 --- a/core/java/android/print/IPrintSpoolerClient.aidl +++ b/core/java/android/print/IPrintSpoolerClient.aidl @@ -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(); } diff --git a/core/java/android/print/IPrinterDiscoveryObserver.aidl b/core/java/android/print/IPrinterDiscoveryObserver.aidl new file mode 100644 index 0000000..625f383 --- /dev/null +++ b/core/java/android/print/IPrinterDiscoveryObserver.aidl @@ -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); +} diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index 531dcb2..d3e35c3 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -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; diff --git a/core/java/android/print/PrinterDiscoverySession.java b/core/java/android/print/PrinterDiscoverySession.java new file mode 100644 index 0000000..8fbdd9c --- /dev/null +++ b/core/java/android/print/PrinterDiscoverySession.java @@ -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(); + } + } + } +} |