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

Commit fa04bc7a authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by android-build-merger
Browse files

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

am: 740a5f02

* commit '740a5f02':
  Add the print service recommendation service

Change-Id: Ie58ade9356f591781496581259b6d8a876780ac9
parents e6fcfeae 740a5f02
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