Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 740a5f02 authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by Android (Google) Code Review
Browse files

Merge "Add the print service recommendation service" into nyc-dev

parents bc2294b3 9dcb86a4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -251,10 +251,13 @@ LOCAL_SRC_FILES += \
	core/java/android/print/IPrintDocumentAdapterObserver.aidl \
	core/java/android/print/IPrintJobStateChangeListener.aidl \
	core/java/android/print/IPrintServicesChangeListener.aidl \
	core/java/android/printservice/recommendation/IRecommendationsChangeListener.aidl \
	core/java/android/print/IPrintManager.aidl \
	core/java/android/print/IPrintSpooler.aidl \
	core/java/android/print/IPrintSpoolerCallbacks.aidl \
	core/java/android/print/IPrintSpoolerClient.aidl \
	core/java/android/printservice/recommendation/IRecommendationServiceCallbacks.aidl \
	core/java/android/printservice/recommendation/IRecommendationService.aidl \
	core/java/android/print/IWriteResultCallback.aidl \
	core/java/android/printservice/IPrintService.aidl \
	core/java/android/printservice/IPrintServiceClient.aidl \
@@ -565,6 +568,7 @@ aidl_files := \
	frameworks/base/core/java/android/print/PrintJobInfo.aidl \
	frameworks/base/core/java/android/print/PrinterInfo.aidl \
	frameworks/base/core/java/android/print/PrintJobId.aidl \
	frameworks/base/core/java/android/printservice/recommendation/RecommendationInfo.aidl \
	frameworks/base/core/java/android/hardware/usb/UsbDevice.aidl \
	frameworks/base/core/java/android/hardware/usb/UsbInterface.aidl \
	frameworks/base/core/java/android/hardware/usb/UsbEndpoint.aidl \
+25 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ package android {
    field public static final java.lang.String BIND_MIDI_DEVICE_SERVICE = "android.permission.BIND_MIDI_DEVICE_SERVICE";
    field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
    field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
    field public static final java.lang.String BIND_PRINT_RECOMMENDATION_SERVICE = "android.permission.BIND_PRINT_RECOMMENDATION_SERVICE";
    field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
    field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
    field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
@@ -32702,6 +32703,30 @@ package android.printservice {
}
package android.printservice.recommendation {
  public final class RecommendationInfo implements android.os.Parcelable {
    ctor public RecommendationInfo(java.lang.CharSequence, java.lang.CharSequence, int, boolean);
    method public int describeContents();
    method public java.lang.CharSequence getName();
    method public int getNumDiscoveredPrinters();
    method public java.lang.CharSequence getPackageName();
    method public boolean recommendsMultiVendorService();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.printservice.recommendation.RecommendationInfo> CREATOR;
  }
  public abstract class RecommendationService extends android.app.Service {
    ctor public RecommendationService();
    method public final android.os.IBinder onBind(android.content.Intent);
    method public abstract void onConnected();
    method public abstract void onDisconnected();
    method public final boolean onUnbind(android.content.Intent);
    method public final void updateRecommendations(java.util.List<android.printservice.recommendation.RecommendationInfo>);
  }
}
package android.provider {
  public final class AlarmClock {
+33 −1
Original line number Diff line number Diff line
@@ -24,9 +24,11 @@ import android.print.IPrintDocumentAdapter;
import android.print.PrintJobId;
import android.print.IPrintJobStateChangeListener;
import android.print.IPrintServicesChangeListener;
import android.printservice.recommendation.IRecommendationsChangeListener;
import android.print.PrinterId;
import android.print.PrintJobInfo;
import android.print.PrintAttributes;
import android.printservice.recommendation.RecommendationInfo;
import android.printservice.PrintServiceInfo;

/**
@@ -73,7 +75,6 @@ interface IPrintManager {
     * Get the print services.
     *
     * @param selectionFlags flags selecting which services to get
     * @param selectedService if not null, the id of the print service to get
     * @param userId the id of the user requesting the services
     *
     * @return the list of selected print services.
@@ -89,6 +90,37 @@ interface IPrintManager {
     */
    void setPrintServiceEnabled(in ComponentName service, boolean isEnabled, int userId);

    /**
     * Listen for changes to the print service recommendations.
     *
     * @param listener the listener to add
     * @param userId the id of the user listening
     *
     * @see android.print.PrintManager#getPrintServiceRecommendations
     */
    void addPrintServiceRecommendationsChangeListener(in IRecommendationsChangeListener listener,
            int userId);

    /**
     * Stop listening for changes to the print service recommendations.
     *
     * @param listener the listener to remove
     * @param userId the id of the user requesting the removal
     *
     * @see android.print.PrintManager#getPrintServiceRecommendations
     */
    void removePrintServiceRecommendationsChangeListener(in IRecommendationsChangeListener listener,
            int userId);

    /**
     * Get the print service recommendations.
     *
     * @param userId the id of the user requesting the recommendations
     *
     * @return the list of selected print services.
     */
    List<RecommendationInfo> getPrintServiceRecommendations(int userId);

    void createPrinterDiscoverySession(in IPrinterDiscoveryObserver observer, int userId);
    void startPrinterDiscovery(in IPrinterDiscoveryObserver observer,
            in List<PrinterId> priorityList, int userId);
+151 −5
Original line number Diff line number Diff line
@@ -36,12 +36,15 @@ import android.os.RemoteException;
import android.print.PrintDocumentAdapter.LayoutResultCallback;
import android.print.PrintDocumentAdapter.WriteResultCallback;
import android.printservice.PrintServiceInfo;
import android.printservice.recommendation.IRecommendationsChangeListener;
import android.printservice.recommendation.RecommendationInfo;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.os.SomeArgs;

import com.android.internal.util.Preconditions;
import libcore.io.IoUtils;

import java.lang.ref.WeakReference;
@@ -113,6 +116,7 @@ public final class PrintManager {

    private static final int MSG_NOTIFY_PRINT_JOB_STATE_CHANGED = 1;
    private static final int MSG_NOTIFY_PRINT_SERVICES_CHANGED = 2;
    private static final int MSG_NOTIFY_PRINT_SERVICE_RECOMMENDATIONS_CHANGED = 3;

    /**
     * Package name of print spooler.
@@ -202,6 +206,9 @@ public final class PrintManager {
            mPrintJobStateChangeListeners;
    private Map<PrintServicesChangeListener, PrintServicesChangeListenerWrapper>
            mPrintServicesChangeListeners;
    private Map<PrintServiceRecommendationsChangeListener,
            PrintServiceRecommendationsChangeListenerWrapper>
            mPrintServiceRecommendationsChangeListeners;

    /** @hide */
    public interface PrintJobStateChangeListener {
@@ -223,6 +230,15 @@ public final class PrintManager {
        public void onPrintServicesChanged();
    }

    /** @hide */
    public interface PrintServiceRecommendationsChangeListener {

        /**
         * Callback notifying that the print service recommendations changed.
         */
        void onPrintServiceRecommendationsChanged();
    }

    /**
     * Creates a new instance.
     *
@@ -260,7 +276,14 @@ public final class PrintManager {
                            listener.onPrintServicesChanged();
                        }
                    } break;

                    case MSG_NOTIFY_PRINT_SERVICE_RECOMMENDATIONS_CHANGED: {
                        PrintServiceRecommendationsChangeListenerWrapper wrapper =
                                (PrintServiceRecommendationsChangeListenerWrapper) message.obj;
                        PrintServiceRecommendationsChangeListener listener = wrapper.getListener();
                        if (listener != null) {
                            listener.onPrintServiceRecommendationsChanged();
                        }
                    } break;
                }
            }
        };
@@ -539,13 +562,14 @@ public final class PrintManager {
     * @see android.print.PrintManager#getPrintServices
     */
    void addPrintServicesChangeListener(@NonNull PrintServicesChangeListener listener) {
        Preconditions.checkNotNull(listener);

        if (mService == null) {
            Log.w(LOG_TAG, "Feature android.software.print not available");
            return;
        }
        if (mPrintServicesChangeListeners == null) {
            mPrintServicesChangeListeners = new ArrayMap<PrintServicesChangeListener,
                    PrintServicesChangeListenerWrapper>();
            mPrintServicesChangeListeners = new ArrayMap<>();
        }
        PrintServicesChangeListenerWrapper wrappedListener =
                new PrintServicesChangeListenerWrapper(listener, mHandler);
@@ -565,6 +589,8 @@ public final class PrintManager {
     * @see android.print.PrintManager#getPrintServices
     */
    void removePrintServicesChangeListener(@NonNull PrintServicesChangeListener listener) {
        Preconditions.checkNotNull(listener);

        if (mService == null) {
            Log.w(LOG_TAG, "Feature android.software.print not available");
            return;
@@ -588,7 +614,6 @@ public final class PrintManager {
        }
    }


    /**
     * Gets the list of print services, but does not register for updates. The user has to register
     * for updates by itself, or use {@link PrintServicesLoader}.
@@ -596,7 +621,7 @@ public final class PrintManager {
     * @param selectionFlags flags selecting which services to get. Either
     *                       {@link #ENABLED_SERVICES},{@link #DISABLED_SERVICES}, or both.
     *
     * @return The enabled service list or an empty list.
     * @return The print service list or an empty list.
     *
     * @see #addPrintServicesChangeListener(PrintServicesChangeListener)
     * @see #removePrintServicesChangeListener(PrintServicesChangeListener)
@@ -604,6 +629,8 @@ public final class PrintManager {
     * @hide
     */
    public @NonNull List<PrintServiceInfo> getPrintServices(int selectionFlags) {
        Preconditions.checkFlagsArgument(selectionFlags, ALL_SERVICES);

        try {
            List<PrintServiceInfo> services = mService.getPrintServices(selectionFlags, mUserId);
            if (services != null) {
@@ -615,6 +642,92 @@ public final class PrintManager {
        return Collections.emptyList();
    }

    /**
     * Listen for changes to the print service recommendations.
     *
     * @param listener the listener to add
     *
     * @see android.print.PrintManager#getPrintServiceRecommendations
     */
    void addPrintServiceRecommendationsChangeListener(
            @NonNull PrintServiceRecommendationsChangeListener listener) {
        Preconditions.checkNotNull(listener);

        if (mService == null) {
            Log.w(LOG_TAG, "Feature android.software.print not available");
            return;
        }
        if (mPrintServiceRecommendationsChangeListeners == null) {
            mPrintServiceRecommendationsChangeListeners = new ArrayMap<>();
        }
        PrintServiceRecommendationsChangeListenerWrapper wrappedListener =
                new PrintServiceRecommendationsChangeListenerWrapper(listener, mHandler);
        try {
            mService.addPrintServiceRecommendationsChangeListener(wrappedListener, mUserId);
            mPrintServiceRecommendationsChangeListeners.put(listener, wrappedListener);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Stop listening for changes to the print service recommendations.
     *
     * @param listener the listener to remove
     *
     * @see android.print.PrintManager#getPrintServiceRecommendations
     */
    void removePrintServiceRecommendationsChangeListener(
            @NonNull PrintServiceRecommendationsChangeListener listener) {
        Preconditions.checkNotNull(listener);

        if (mService == null) {
            Log.w(LOG_TAG, "Feature android.software.print not available");
            return;
        }
        if (mPrintServiceRecommendationsChangeListeners == null) {
            return;
        }
        PrintServiceRecommendationsChangeListenerWrapper wrappedListener =
                mPrintServiceRecommendationsChangeListeners.remove(listener);
        if (wrappedListener == null) {
            return;
        }
        if (mPrintServiceRecommendationsChangeListeners.isEmpty()) {
            mPrintServiceRecommendationsChangeListeners = null;
        }
        wrappedListener.destroy();
        try {
            mService.removePrintServiceRecommendationsChangeListener(wrappedListener, mUserId);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Gets the list of print service recommendations, but does not register for updates. The user
     * has to register for updates by itself, or use {@link PrintServiceRecommendationsLoader}.
     *
     * @return The print service recommendations list or an empty list.
     *
     * @see #addPrintServiceRecommendationsChangeListener
     * @see #removePrintServiceRecommendationsChangeListener
     *
     * @hide
     */
    public @NonNull List<RecommendationInfo> getPrintServiceRecommendations() {
        try {
            List<RecommendationInfo> recommendations =
                    mService.getPrintServiceRecommendations(mUserId);
            if (recommendations != null) {
                return recommendations;
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return Collections.emptyList();
    }

    /**
     * @hide
     */
@@ -1242,4 +1355,37 @@ public final class PrintManager {
            return mWeakListener.get();
        }
    }

    /**
     * @hide
     */
    public static final class PrintServiceRecommendationsChangeListenerWrapper extends
            IRecommendationsChangeListener.Stub {
        private final WeakReference<PrintServiceRecommendationsChangeListener> mWeakListener;
        private final WeakReference<Handler> mWeakHandler;

        public PrintServiceRecommendationsChangeListenerWrapper(
                PrintServiceRecommendationsChangeListener listener, Handler handler) {
            mWeakListener = new WeakReference<>(listener);
            mWeakHandler = new WeakReference<>(handler);
        }

        @Override
        public void onRecommendationsChanged() {
            Handler handler = mWeakHandler.get();
            PrintServiceRecommendationsChangeListener listener = mWeakListener.get();
            if (handler != null && listener != null) {
                handler.obtainMessage(MSG_NOTIFY_PRINT_SERVICE_RECOMMENDATIONS_CHANGED,
                        this).sendToTarget();
            }
        }

        public void destroy() {
            mWeakListener.clear();
        }

        public PrintServiceRecommendationsChangeListener getListener() {
            return mWeakListener.get();
        }
    }
}
+121 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.annotation.NonNull;
import android.content.Context;
import android.content.Loader;
import android.os.Handler;
import android.os.Message;
import android.printservice.recommendation.RecommendationInfo;
import com.android.internal.util.Preconditions;

import java.util.List;

/**
 * Loader for the list of print service recommendations.
 *
 * @hide
 */
public class PrintServiceRecommendationsLoader extends Loader<List<RecommendationInfo>> {
    /** The print manager to be used by this object */
    private final @NonNull PrintManager mPrintManager;

    /** Handler to sequentialize the delivery of the results to the main thread */
    private final Handler mHandler;

    /** Listens for updates to the data from the platform */
    private PrintManager.PrintServiceRecommendationsChangeListener mListener;

    /**
     * Create a new PrintServicesLoader.
     *
     * @param printManager The print manager supplying the data
     * @param context      Context of the using object
     */
    public PrintServiceRecommendationsLoader(@NonNull PrintManager printManager,
            @NonNull Context context) {
        super(Preconditions.checkNotNull(context));
        mHandler = new MyHandler();
        mPrintManager = Preconditions.checkNotNull(printManager);
    }

    @Override
    protected void onForceLoad() {
        queueNewResult();
    }

    /**
     * Read the print service recommendations and queue it to be delivered on the main thread.
     */
    private void queueNewResult() {
        Message m = mHandler.obtainMessage(0);
        m.obj = mPrintManager.getPrintServiceRecommendations();
        mHandler.sendMessage(m);
    }

    @Override
    protected void onStartLoading() {
        mListener = new PrintManager.PrintServiceRecommendationsChangeListener() {
            @Override
            public void onPrintServiceRecommendationsChanged() {
                queueNewResult();
            }
        };

        mPrintManager.addPrintServiceRecommendationsChangeListener(mListener);

        // Immediately deliver a result
        deliverResult(mPrintManager.getPrintServiceRecommendations());
    }

    @Override
    protected void onStopLoading() {
        if (mListener != null) {
            mPrintManager.removePrintServiceRecommendationsChangeListener(mListener);
            mListener = null;
        }

        if (mHandler != null) {
            mHandler.removeMessages(0);
        }
    }

    @Override
    protected void onReset() {
        onStopLoading();
    }

    /**
     * Handler to sequentialize all the updates to the main thread.
     */
    private class MyHandler extends Handler {
        /**
         * Create a new handler on the main thread.
         */
        public MyHandler() {
            super(getContext().getMainLooper());
        }

        @Override
        public void handleMessage(Message msg) {
            if (isStarted()) {
                deliverResult((List<RecommendationInfo>) msg.obj);
            }
        }
    }
}
Loading