14b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/*
24b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Copyright (C) 2013 The Android Open Source Project
34b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov *
44b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
54b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * you may not use this file except in compliance with the License.
64b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * You may obtain a copy of the License at
74b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov *
84b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
94b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov *
104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software
114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * See the License for the specific language governing permissions and
144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * limitations under the License.
154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */
164b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
174b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovpackage android.print;
184b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
19c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmannimport android.annotation.NonNull;
20c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmannimport android.annotation.Nullable;
21c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann
2222f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmannimport java.util.Objects;
2322f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann
244b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/**
254d4c66dd38e940082e385b49a33f4022ab04c738Svetoslav Ganov * This class represents a print job from the perspective of an
264d4c66dd38e940082e385b49a33f4022ab04c738Svetoslav Ganov * application. It contains behavior methods for performing operations
274d4c66dd38e940082e385b49a33f4022ab04c738Svetoslav Ganov * on it as well as methods for querying its state. A snapshot of the
284d4c66dd38e940082e385b49a33f4022ab04c738Svetoslav Ganov * print job state is represented by the {@link PrintJobInfo} class.
294d4c66dd38e940082e385b49a33f4022ab04c738Svetoslav Ganov * The state of a print job may change over time. An application receives
304d4c66dd38e940082e385b49a33f4022ab04c738Svetoslav Ganov * instances of this class when creating a print job or querying for
314d4c66dd38e940082e385b49a33f4022ab04c738Svetoslav Ganov * its print jobs.
324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */
334b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovpublic final class PrintJob {
344b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
3522f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann    private final @NonNull PrintManager mPrintManager;
364b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
3722f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann    private @NonNull PrintJobInfo mCachedInfo;
384b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
3922f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann    PrintJob(@NonNull PrintJobInfo info, @NonNull PrintManager printManager) {
404b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        mCachedInfo = info;
414b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        mPrintManager = printManager;
424b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    }
434b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
444b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    /**
454b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     * Gets the unique print job id.
464b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     *
474b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     * @return The id.
484b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     */
4922f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann    public @Nullable PrintJobId getId() {
502fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        return mCachedInfo.getId();
514b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    }
524b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
534b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    /**
544b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     * Gets the {@link PrintJobInfo} that describes this job.
554b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     * <p>
564b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     * <strong>Node:</strong>The returned info object is a snapshot of the
574b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     * current print job state. Every call to this method returns a fresh
584b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     * info object that reflects the current print job state.
594b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     * </p>
604b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     *
614b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     * @return The print job info.
624b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     */
6322f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann    public @NonNull PrintJobInfo getInfo() {
6485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        if (isInImmutableState()) {
6585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            return mCachedInfo;
6685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        }
672fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        PrintJobInfo info = mPrintManager.getPrintJobInfo(mCachedInfo.getId());
684b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        if (info != null) {
694b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov            mCachedInfo = info;
704b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        }
714b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        return mCachedInfo;
724b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    }
734b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
744b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    /**
75704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * Cancels this print job. You can request cancellation of a
76704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * queued, started, blocked, or failed print job.
77704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
78704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @see #isQueued()
79704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @see #isStarted()
80704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @see #isBlocked()
81704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @see #isFailed()
824b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov     */
834b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    public void cancel() {
84704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        final int state = getInfo().getState();
85704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        if (state == PrintJobInfo.STATE_QUEUED
86704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov                || state == PrintJobInfo.STATE_STARTED
87704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov                || state == PrintJobInfo.STATE_BLOCKED
88704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov                || state == PrintJobInfo.STATE_FAILED) {
892fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            mPrintManager.cancelPrintJob(mCachedInfo.getId());
9085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        }
9185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov    }
9285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov
93704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    /**
94704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * Restarts this print job. You can request restart of a failed
95704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * print job.
96704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
97704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @see #isFailed()
98704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     */
99704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    public void restart() {
100704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        if (isFailed()) {
101704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov            mPrintManager.restartPrintJob(mCachedInfo.getId());
102704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        }
103704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    }
104704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
105704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    /**
106704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * Gets whether this print job is queued. Such a print job is
107704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * ready to be printed. You can request a cancellation via
108704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * {@link #cancel()}.
109704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
110704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @return Whether the print job is queued.
111704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
112704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @see #cancel()
113704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     */
114704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    public boolean isQueued() {
115704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        return getInfo().getState() == PrintJobInfo.STATE_QUEUED;
116704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    }
117704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
118704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    /**
119704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * Gets whether this print job is started. Such a print job is
120704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * being printed. You can request a cancellation via
121704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * {@link #cancel()}.
122704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
123704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @return Whether the print job is started.
124704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
125704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @see #cancel()
126704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     */
127704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    public boolean isStarted() {
128704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        return getInfo().getState() == PrintJobInfo.STATE_STARTED;
129704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    }
130704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
131704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    /**
132704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * Gets whether this print job is blocked. Such a print job is halted
133704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * due to an abnormal condition. You can request a cancellation via
134704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * {@link #cancel()}.
135704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
136704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @return Whether the print job is blocked.
137704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
138704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @see #cancel()
139704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     */
140704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    public boolean isBlocked() {
141704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        return getInfo().getState() == PrintJobInfo.STATE_BLOCKED;
142704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    }
143704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
144704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    /**
145704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * Gets whether this print job is completed. Such a print job
146704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * is successfully printed. You can neither cancel nor restart
147704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * such a print job.
148704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
149704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @return Whether the print job is completed.
150704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     */
151704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    public boolean isCompleted() {
152704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        return getInfo().getState() == PrintJobInfo.STATE_COMPLETED;
153704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    }
154704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
155704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    /**
156704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * Gets whether this print job is failed. Such a print job is
157704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * not successfully printed due to an error. You can request
1584d4c66dd38e940082e385b49a33f4022ab04c738Svetoslav Ganov     * a restart via {@link #restart()} or cancel via {@link #cancel()}.
159704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
160704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @return Whether the print job is failed.
161704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
162704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @see #restart()
1634d4c66dd38e940082e385b49a33f4022ab04c738Svetoslav Ganov     * @see #cancel()
164704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     */
165704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    public boolean isFailed() {
166704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        return getInfo().getState() == PrintJobInfo.STATE_FAILED;
167704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    }
168704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
169704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    /**
170704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * Gets whether this print job is cancelled. Such a print job was
171704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * cancelled as a result of a user request. This is a final state.
172704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * You cannot restart such a print job.
173704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     *
174704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     * @return Whether the print job is cancelled.
175704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov     */
176704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    public boolean isCancelled() {
177704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        return getInfo().getState() == PrintJobInfo.STATE_CANCELED;
178704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    }
179704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
18085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov    private boolean isInImmutableState() {
18185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        final int state = mCachedInfo.getState();
18285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        return state == PrintJobInfo.STATE_COMPLETED
18385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                || state == PrintJobInfo.STATE_CANCELED;
1844b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    }
1854b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
1864b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    @Override
1874b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    public boolean equals(Object obj) {
1884b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        if (this == obj) {
1894b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov            return true;
1904b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        }
1914b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        if (obj == null) {
1924b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov            return false;
1934b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        }
1944b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        if (getClass() != obj.getClass()) {
1954b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov            return false;
1964b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        }
1974b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        PrintJob other = (PrintJob) obj;
19822f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann        return Objects.equals(mCachedInfo.getId(), other.mCachedInfo.getId());
1994b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    }
2004b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
2014b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    @Override
2024b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    public int hashCode() {
20322f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann        PrintJobId printJobId = mCachedInfo.getId();
20422f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann
20522f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann        if (printJobId == null) {
20622f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann            return 0;
20722f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann        } else {
20822f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann            return printJobId.hashCode();
20922f86b4e77c77312e8b3f08fc598be00c323f750Philip P. Moltmann        }
2104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    }
2114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov}
212