13bf66744d61d18c66d46f2608de0467ad3df0268Mopria/*
23bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 The Android Open Source Project
33bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 Mopria Alliance, Inc.
43bf66744d61d18c66d46f2608de0467ad3df0268Mopria *
53bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Licensed under the Apache License, Version 2.0 (the "License");
63bf66744d61d18c66d46f2608de0467ad3df0268Mopria * you may not use this file except in compliance with the License.
73bf66744d61d18c66d46f2608de0467ad3df0268Mopria * You may obtain a copy of the License at
83bf66744d61d18c66d46f2608de0467ad3df0268Mopria *
93bf66744d61d18c66d46f2608de0467ad3df0268Mopria *      http://www.apache.org/licenses/LICENSE-2.0
103bf66744d61d18c66d46f2608de0467ad3df0268Mopria *
113bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Unless required by applicable law or agreed to in writing, software
123bf66744d61d18c66d46f2608de0467ad3df0268Mopria * distributed under the License is distributed on an "AS IS" BASIS,
133bf66744d61d18c66d46f2608de0467ad3df0268Mopria * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143bf66744d61d18c66d46f2608de0467ad3df0268Mopria * See the License for the specific language governing permissions and
153bf66744d61d18c66d46f2608de0467ad3df0268Mopria * limitations under the License.
163bf66744d61d18c66d46f2608de0467ad3df0268Mopria */
173bf66744d61d18c66d46f2608de0467ad3df0268Mopria
183bf66744d61d18c66d46f2608de0467ad3df0268Mopriapackage com.android.bips.ipp;
193bf66744d61d18c66d46f2608de0467ad3df0268Mopria
203bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.content.Context;
213bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.content.pm.PackageInfo;
223bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.content.pm.PackageManager;
233bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.net.Uri;
243bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.os.AsyncTask;
253bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.os.Build;
263bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.os.Handler;
273bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.printservice.PrintJob;
283bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.text.TextUtils;
293bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.util.Log;
303bf66744d61d18c66d46f2608de0467ad3df0268Mopria
313bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.R;
323bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.jni.BackendConstants;
333bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.jni.JobCallback;
343bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.jni.JobCallbackParams;
353bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.jni.LocalJobParams;
363bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.jni.LocalPrinterCapabilities;
373bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.jni.PdfRender;
383bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.util.FileUtils;
393bf66744d61d18c66d46f2608de0467ad3df0268Mopria
403bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport java.io.File;
413bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport java.util.Locale;
423bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport java.util.function.Consumer;
433bf66744d61d18c66d46f2608de0467ad3df0268Mopria
443bf66744d61d18c66d46f2608de0467ad3df0268Mopriapublic class Backend implements JobCallback {
453bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private static final String TAG = Backend.class.getSimpleName();
463bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private static final boolean DEBUG = false;
473bf66744d61d18c66d46f2608de0467ad3df0268Mopria
483bf66744d61d18c66d46f2608de0467ad3df0268Mopria    static final String TEMP_JOB_FOLDER = "jobs";
493bf66744d61d18c66d46f2608de0467ad3df0268Mopria
503bf66744d61d18c66d46f2608de0467ad3df0268Mopria    // Error codes strictly to be in negative number
513bf66744d61d18c66d46f2608de0467ad3df0268Mopria    static final int ERROR_FILE = -1;
523bf66744d61d18c66d46f2608de0467ad3df0268Mopria    static final int ERROR_CANCEL = -2;
533bf66744d61d18c66d46f2608de0467ad3df0268Mopria    static final int ERROR_UNKNOWN = -3;
543bf66744d61d18c66d46f2608de0467ad3df0268Mopria
553bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private static final String VERSION_UNKNOWN = "(unknown)";
563bf66744d61d18c66d46f2608de0467ad3df0268Mopria
573bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private final Handler mMainHandler;
583bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private final Context mContext;
593bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private JobStatus mCurrentJobStatus;
603bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private Consumer<JobStatus> mJobStatusListener;
613bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private AsyncTask<Void, Void, Integer> mStartTask;
623bf66744d61d18c66d46f2608de0467ad3df0268Mopria
633bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public Backend(Context context) {
643bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (DEBUG) Log.d(TAG, "Backend()");
653bf66744d61d18c66d46f2608de0467ad3df0268Mopria
663bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mContext = context;
673bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mMainHandler = new Handler(context.getMainLooper());
683bf66744d61d18c66d46f2608de0467ad3df0268Mopria        PdfRender.getInstance(mContext);
693bf66744d61d18c66d46f2608de0467ad3df0268Mopria
703bf66744d61d18c66d46f2608de0467ad3df0268Mopria        // Load required JNI libraries
713bf66744d61d18c66d46f2608de0467ad3df0268Mopria        System.loadLibrary(BackendConstants.WPRINT_LIBRARY_PREFIX);
723bf66744d61d18c66d46f2608de0467ad3df0268Mopria
733bf66744d61d18c66d46f2608de0467ad3df0268Mopria        // Create and initialize JNI layer
743bf66744d61d18c66d46f2608de0467ad3df0268Mopria        nativeInit(this, context.getApplicationInfo().dataDir, Build.VERSION.SDK_INT);
753bf66744d61d18c66d46f2608de0467ad3df0268Mopria        nativeSetSourceInfo(context.getString(R.string.app_name).toLowerCase(Locale.US),
763bf66744d61d18c66d46f2608de0467ad3df0268Mopria                getApplicationVersion(context).toLowerCase(Locale.US),
773bf66744d61d18c66d46f2608de0467ad3df0268Mopria                BackendConstants.WPRINT_APPLICATION_ID.toLowerCase(Locale.US));
783bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
793bf66744d61d18c66d46f2608de0467ad3df0268Mopria
803bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /** Return the current application version or VERISON_UNKNOWN */
813bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private String getApplicationVersion(Context context) {
823bf66744d61d18c66d46f2608de0467ad3df0268Mopria        try {
833bf66744d61d18c66d46f2608de0467ad3df0268Mopria            PackageInfo packageInfo = context.getPackageManager()
843bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    .getPackageInfo(context.getPackageName(), 0);
853bf66744d61d18c66d46f2608de0467ad3df0268Mopria            return packageInfo.versionName;
863bf66744d61d18c66d46f2608de0467ad3df0268Mopria        } catch (PackageManager.NameNotFoundException e) {
873bf66744d61d18c66d46f2608de0467ad3df0268Mopria            return VERSION_UNKNOWN;
883bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
893bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
903bf66744d61d18c66d46f2608de0467ad3df0268Mopria
913bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /** Asynchronously get printer capabilities, returning results or null to a callback */
92e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney    public AsyncTask<?, ?, ?> getCapabilities(Uri uri, long timeout,
933bf66744d61d18c66d46f2608de0467ad3df0268Mopria            final Consumer<LocalPrinterCapabilities> capabilitiesConsumer) {
943bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (DEBUG) Log.d(TAG, "getCapabilities()");
953bf66744d61d18c66d46f2608de0467ad3df0268Mopria
96e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney        return new GetCapabilitiesTask(this, uri, timeout) {
973bf66744d61d18c66d46f2608de0467ad3df0268Mopria            @Override
983bf66744d61d18c66d46f2608de0467ad3df0268Mopria            protected void onPostExecute(LocalPrinterCapabilities result) {
993bf66744d61d18c66d46f2608de0467ad3df0268Mopria                capabilitiesConsumer.accept(result);
1003bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
1013bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
1023bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1033bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1043bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
1053bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Start a print job. Results will be notified to the listener. Do not start more than
1063bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * one job at a time.
1073bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
1083bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public void print(Uri uri, PrintJob printJob, LocalPrinterCapabilities capabilities,
1093bf66744d61d18c66d46f2608de0467ad3df0268Mopria            Consumer<JobStatus> listener) {
1103bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (DEBUG) Log.d(TAG, "print()");
1113bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1123bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mJobStatusListener = listener;
1133bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mCurrentJobStatus = new JobStatus();
1143bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1153bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mStartTask = new StartJobTask(mContext, this, uri, printJob, capabilities) {
1163bf66744d61d18c66d46f2608de0467ad3df0268Mopria            @Override
1173bf66744d61d18c66d46f2608de0467ad3df0268Mopria            public void onCancelled(Integer result) {
1183bf66744d61d18c66d46f2608de0467ad3df0268Mopria                if (DEBUG) Log.d(TAG, "StartJobTask::onCancelled " + result);
1193bf66744d61d18c66d46f2608de0467ad3df0268Mopria                onPostExecute(ERROR_CANCEL);
1203bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
1213bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1223bf66744d61d18c66d46f2608de0467ad3df0268Mopria            @Override
1233bf66744d61d18c66d46f2608de0467ad3df0268Mopria            protected void onPostExecute(Integer result) {
1243bf66744d61d18c66d46f2608de0467ad3df0268Mopria                if (DEBUG) Log.d(TAG, "StartJobTask::onPostExecute " + result);
1253bf66744d61d18c66d46f2608de0467ad3df0268Mopria                mStartTask = null;
1263bf66744d61d18c66d46f2608de0467ad3df0268Mopria                if (result > 0) {
1273bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    mCurrentJobStatus = new JobStatus.Builder(mCurrentJobStatus).setId(result)
1283bf66744d61d18c66d46f2608de0467ad3df0268Mopria                            .build();
1293bf66744d61d18c66d46f2608de0467ad3df0268Mopria                } else if (mJobStatusListener != null) {
1303bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    String jobResult = BackendConstants.JOB_DONE_ERROR;
1313bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    if (result == ERROR_CANCEL) {
1323bf66744d61d18c66d46f2608de0467ad3df0268Mopria                        jobResult = BackendConstants.JOB_DONE_CANCELLED;
1333bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    } else if (result == ERROR_FILE) {
1343bf66744d61d18c66d46f2608de0467ad3df0268Mopria                        jobResult = BackendConstants.JOB_DONE_CORRUPT;
1353bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    }
1363bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1373bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    // If the start attempt failed and we are still listening, notify and be done
1383bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    mCurrentJobStatus = new JobStatus.Builder()
1393bf66744d61d18c66d46f2608de0467ad3df0268Mopria                            .setJobState(BackendConstants.JOB_STATE_DONE)
1403bf66744d61d18c66d46f2608de0467ad3df0268Mopria                            .setJobResult(jobResult).build();
1413bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    mJobStatusListener.accept(mCurrentJobStatus);
1423bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    mJobStatusListener = null;
1433bf66744d61d18c66d46f2608de0467ad3df0268Mopria                }
1443bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
1453bf66744d61d18c66d46f2608de0467ad3df0268Mopria        };
1463bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mStartTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
1473bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1483bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1493bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /** Attempt to cancel the current job */
1503bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public void cancel() {
1513bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (DEBUG) Log.d(TAG, "cancel()");
1523bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1533bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (mStartTask != null) {
1543bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (DEBUG) Log.d(TAG, "cancelling start task");
1553bf66744d61d18c66d46f2608de0467ad3df0268Mopria            mStartTask.cancel(true);
1563bf66744d61d18c66d46f2608de0467ad3df0268Mopria        } else if (mCurrentJobStatus != null && mCurrentJobStatus.getId() != JobStatus.ID_UNKNOWN) {
1573bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (DEBUG) Log.d(TAG, "cancelling job via new task");
1583bf66744d61d18c66d46f2608de0467ad3df0268Mopria            new CancelJobTask(this, mCurrentJobStatus.getId())
1593bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
1603bf66744d61d18c66d46f2608de0467ad3df0268Mopria        } else {
1613bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (DEBUG) Log.d(TAG, "Nothing to cancel in backend, ignoring");
1623bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
1633bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1643bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1653bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
1663bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Call when it is safe to release document-centric resources related to a print job
1673bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
1683bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public void closeDocument() {
1693bf66744d61d18c66d46f2608de0467ad3df0268Mopria        // Tell the renderer it may release resources for the document
1703bf66744d61d18c66d46f2608de0467ad3df0268Mopria        PdfRender.getInstance(mContext).closeDocument();
1713bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1723bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1733bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
1743bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Call when service is shutting down, nothing else is happening, and this object
1753bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * is no longer required. After closing this object it should be discarded.
1763bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
1773bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public void close() {
1783bf66744d61d18c66d46f2608de0467ad3df0268Mopria        nativeExit();
1793bf66744d61d18c66d46f2608de0467ad3df0268Mopria        PdfRender.getInstance(mContext).close();
1803bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1813bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1823bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /** Called by JNI */
1833bf66744d61d18c66d46f2608de0467ad3df0268Mopria    @Override
1843bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public void jobCallback(final int jobId, final JobCallbackParams params) {
1853bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mMainHandler.post(() -> {
1863bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (DEBUG) Log.d(TAG, "jobCallback() jobId=" + jobId + ", params=" + params);
1873bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1883bf66744d61d18c66d46f2608de0467ad3df0268Mopria            JobStatus.Builder builder = new JobStatus.Builder(mCurrentJobStatus);
1893bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1903bf66744d61d18c66d46f2608de0467ad3df0268Mopria            builder.setId(params.jobId);
1913bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1923bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (!TextUtils.isEmpty(params.printerState)) {
1933bf66744d61d18c66d46f2608de0467ad3df0268Mopria                updateBlockedReasons(builder, params);
1943bf66744d61d18c66d46f2608de0467ad3df0268Mopria            } else if (!TextUtils.isEmpty(params.jobState)) {
1953bf66744d61d18c66d46f2608de0467ad3df0268Mopria                builder.setJobState(params.jobState);
1963bf66744d61d18c66d46f2608de0467ad3df0268Mopria                if (!TextUtils.isEmpty(params.jobDoneResult)) {
1973bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    builder.setJobResult(params.jobDoneResult);
1983bf66744d61d18c66d46f2608de0467ad3df0268Mopria                }
1993bf66744d61d18c66d46f2608de0467ad3df0268Mopria                updateBlockedReasons(builder, params);
2003bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
2013bf66744d61d18c66d46f2608de0467ad3df0268Mopria            mCurrentJobStatus = builder.build();
2023bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2033bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (mJobStatusListener != null) {
2043bf66744d61d18c66d46f2608de0467ad3df0268Mopria                mJobStatusListener.accept(mCurrentJobStatus);
2053bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
2063bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2073bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (mCurrentJobStatus.isJobDone()) {
2083bf66744d61d18c66d46f2608de0467ad3df0268Mopria                nativeEndJob(jobId);
2093bf66744d61d18c66d46f2608de0467ad3df0268Mopria                // Reset status for next job.
2103bf66744d61d18c66d46f2608de0467ad3df0268Mopria                mCurrentJobStatus = new JobStatus();
2113bf66744d61d18c66d46f2608de0467ad3df0268Mopria                mJobStatusListener = null;
2123bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2133bf66744d61d18c66d46f2608de0467ad3df0268Mopria                FileUtils.deleteAll(new File(mContext.getFilesDir(), Backend.TEMP_JOB_FOLDER));
2143bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
2153bf66744d61d18c66d46f2608de0467ad3df0268Mopria        });
2163bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
2173bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2183bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /** Update the blocked reason list with non-empty strings */
2193bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private void updateBlockedReasons(JobStatus.Builder builder, JobCallbackParams params) {
2203bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if ((params.blockedReasons != null) && (params.blockedReasons.length > 0)) {
2213bf66744d61d18c66d46f2608de0467ad3df0268Mopria            builder.clearBlockedReasons();
2223bf66744d61d18c66d46f2608de0467ad3df0268Mopria            for (String reason : params.blockedReasons) {
2233bf66744d61d18c66d46f2608de0467ad3df0268Mopria                if (!TextUtils.isEmpty(reason)) {
2243bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    builder.addBlockedReason(reason);
2253bf66744d61d18c66d46f2608de0467ad3df0268Mopria                }
2263bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
2273bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
2283bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
2293bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2303bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
2313bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Extracts the ip portion of x.x.x.x/y/z
2323bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
2333bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param address any string in the format xxx/yyy/zzz
2343bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @return the part before the "/" or "xxx" in this case
2353bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
2363bf66744d61d18c66d46f2608de0467ad3df0268Mopria    static String getIp(String address) {
2373bf66744d61d18c66d46f2608de0467ad3df0268Mopria        int i = address.indexOf('/');
2383bf66744d61d18c66d46f2608de0467ad3df0268Mopria        return i == -1 ? address : address.substring(0, i);
2393bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
2403bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2413bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
2423bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Initialize the lower layer.
2433bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
2443bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param jobCallback job callback to use whenever job updates arrive
2453bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param dataDir directory to use for temporary files
2463bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param apiVersion local system API version to be supplied to printers
2473bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @return {@link BackendConstants#STATUS_OK} or an error code.
2483bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
2493bf66744d61d18c66d46f2608de0467ad3df0268Mopria    native int nativeInit(JobCallback jobCallback, String dataDir, int apiVersion);
2503bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2513bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
2523bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Supply additional information about the source of jobs.
2533bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
2543bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param appName human-readable name of application providing data to the printer
2553bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param version version of delivering application
2563bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param appId identifier for the delivering application
2573bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
2583bf66744d61d18c66d46f2608de0467ad3df0268Mopria    native void nativeSetSourceInfo(String appName, String version, String appId);
2593bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2603bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
2613bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Request capabilities from a printer.
2623bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
2633bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param address IP address or hostname (e.g. "192.168.1.2")
2643bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param port port to use (e.g. 631)
2653bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param httpResource path of print resource on host (e.g. "/ipp/print")
2663bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param uriScheme scheme (e.g. "ipp")
267e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney     * @param timeout milliseconds to wait before giving up on request
2683bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param capabilities target object to be filled with printer capabilities, if successful
2693bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @return {@link BackendConstants#STATUS_OK} or an error code.
2703bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
2713bf66744d61d18c66d46f2608de0467ad3df0268Mopria    native int nativeGetCapabilities(String address, int port, String httpResource,
272e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney            String uriScheme, long timeout, LocalPrinterCapabilities capabilities);
2733bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2743bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
2753bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Determine initial parameters to be used for jobs
2763bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
2773bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param jobParams object to be filled with default parameters
2783bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @return {@link BackendConstants#STATUS_OK} or an error code.
2793bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
2803bf66744d61d18c66d46f2608de0467ad3df0268Mopria    native int nativeGetDefaultJobParameters(LocalJobParams jobParams);
2813bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2823bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
2833bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Update job parameters to align with known printer capabilities
2843bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
2853bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param jobParams on input, contains requested job parameters; on output contains final
2863bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *                  job parameter selections.
2873bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param capabilities printer capabilities to be used when finalizing job parameters
2883bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @return {@link BackendConstants#STATUS_OK} or an error code.
2893bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
2903bf66744d61d18c66d46f2608de0467ad3df0268Mopria    native int nativeGetFinalJobParameters(LocalJobParams jobParams,
2913bf66744d61d18c66d46f2608de0467ad3df0268Mopria            LocalPrinterCapabilities capabilities);
2923bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2933bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
2943bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Begin job delivery to a target printer. Updates on the job will be sent to the registered
2953bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * {@link JobCallback}.
2963bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
2973bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param address IP address or hostname (e.g. "192.168.1.2")
2983bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param port port to use (e.g. 631)
2993bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param mime_type MIME type of data being sent
3003bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param jobParams job parameters to use when providing the job to the printer
3013bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param capabilities printer capabilities for the printer being used
3023bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param fileList list of files to be provided of the given MIME type
3033bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param debugDir directory to receive debugging information, if any
304fb37766f9429cb26f003c9e81b909637544ff8b4Glade Diviney     * @param scheme URI scheme (e.g. ipp/ipps)
3053bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @return {@link BackendConstants#STATUS_OK} or an error code.
3063bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
3073bf66744d61d18c66d46f2608de0467ad3df0268Mopria    native int nativeStartJob(String address, int port, String mime_type, LocalJobParams jobParams,
308fb37766f9429cb26f003c9e81b909637544ff8b4Glade Diviney            LocalPrinterCapabilities capabilities, String[] fileList, String debugDir, String scheme);
3093bf66744d61d18c66d46f2608de0467ad3df0268Mopria
3103bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
3113bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Request cancellation of the identified job.
3123bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
3133bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param jobId identifier of the job to cancel
3143bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @return {@link BackendConstants#STATUS_OK} or an error code.
3153bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
3163bf66744d61d18c66d46f2608de0467ad3df0268Mopria    native int nativeCancelJob(int jobId);
3173bf66744d61d18c66d46f2608de0467ad3df0268Mopria
3183bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
3193bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Finalizes a job after it is ends for any reason
3203bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
3213bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @param jobId identifier of the job to end
3223bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @return {@link BackendConstants#STATUS_OK} or an error code.
3233bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
3243bf66744d61d18c66d46f2608de0467ad3df0268Mopria    native int nativeEndJob(int jobId);
3253bf66744d61d18c66d46f2608de0467ad3df0268Mopria
3263bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
3273bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Shut down and clean up resources in the JNI layer on system exit
3283bf66744d61d18c66d46f2608de0467ad3df0268Mopria     *
3293bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * @return {@link BackendConstants#STATUS_OK} or an error code.
3303bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
3313bf66744d61d18c66d46f2608de0467ad3df0268Mopria    native int nativeExit();
3323bf66744d61d18c66d46f2608de0467ad3df0268Mopria}
333