1a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav/*
2a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Copyright (C) 2014 The Android Open Source Project
3a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *
4a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Licensed under the Apache License, Version 2.0 (the "License");
5a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * you may not use this file except in compliance with the License.
6a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * You may obtain a copy of the License at
7a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *
8a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *      http://www.apache.org/licenses/LICENSE-2.0
9a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *
10a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Unless required by applicable law or agreed to in writing, software
11a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * distributed under the License is distributed on an "AS IS" BASIS,
12a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * See the License for the specific language governing permissions and
14a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * limitations under the License.
15a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav */
16a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
17a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpackage com.android.printspooler.ui;
18a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
19a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.app.Activity;
20a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.app.LoaderManager.LoaderCallbacks;
21a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.content.Loader;
22a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.Bundle;
23a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.Handler;
24a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.Looper;
25a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.Message;
26a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.PrinterId;
27a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.PrinterInfo;
28a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport com.android.internal.os.SomeArgs;
29a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
30a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.util.ArrayList;
31a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.util.List;
32a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
33a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpublic class PrinterRegistry {
34a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
35a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private static final int LOADER_ID_PRINTERS_LOADER = 1;
36a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
37a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private final Activity mActivity;
38a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
39a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private final List<PrinterInfo> mPrinters = new ArrayList<>();
40a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
41a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private final Runnable mReadyCallback;
42a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
43a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private final Handler mHandler;
44a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
45a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private boolean mReady;
46a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
47a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private OnPrintersChangeListener mOnPrintersChangeListener;
48a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
49a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public interface OnPrintersChangeListener {
50a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public void onPrintersChanged(List<PrinterInfo> printers);
51a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public void onPrintersInvalid();
52a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
53a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
54a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public PrinterRegistry(Activity activity, Runnable readyCallback) {
55a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        mActivity = activity;
56a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        mReadyCallback = readyCallback;
57a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        mHandler = new MyHandler(activity.getMainLooper());
58a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        activity.getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER,
59a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                null, mLoaderCallbacks);
60a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
61a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
62a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public void setOnPrintersChangeListener(OnPrintersChangeListener listener) {
63a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        mOnPrintersChangeListener = listener;
64a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
65a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
66a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public List<PrinterInfo> getPrinters() {
67a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        return mPrinters;
68a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
69a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
70a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public void addHistoricalPrinter(PrinterInfo printer) {
71e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        FusedPrintersProvider provider = getPrinterProvider();
72e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        if (provider != null) {
73e17123dd6d3666c88b47172b8efc995523b47346Svetoslav            getPrinterProvider().addHistoricalPrinter(printer);
74e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        }
75a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
76a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
77a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public void forgetFavoritePrinter(PrinterId printerId) {
78e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        FusedPrintersProvider provider = getPrinterProvider();
79e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        if (provider != null) {
80e17123dd6d3666c88b47172b8efc995523b47346Svetoslav            provider.forgetFavoritePrinter(printerId);
81e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        }
82a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
83a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
84a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public boolean isFavoritePrinter(PrinterId printerId) {
85e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        FusedPrintersProvider provider = getPrinterProvider();
86e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        if (provider != null) {
87e17123dd6d3666c88b47172b8efc995523b47346Svetoslav            return provider.isFavoritePrinter(printerId);
88e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        }
89e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        return false;
90a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
91a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
92a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public void setTrackedPrinter(PrinterId printerId) {
93e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        FusedPrintersProvider provider = getPrinterProvider();
94e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        if (provider != null) {
95e17123dd6d3666c88b47172b8efc995523b47346Svetoslav            provider.setTrackedPrinter(printerId);
96e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        }
97a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
98a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
9948fec5c9a3e4d78bc4cd175fae05be153ac587afSvet Ganov    public boolean areHistoricalPrintersLoaded() {
100e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        FusedPrintersProvider provider = getPrinterProvider();
101e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        if (provider != null) {
102e17123dd6d3666c88b47172b8efc995523b47346Svetoslav            return getPrinterProvider().areHistoricalPrintersLoaded();
103e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        }
104e17123dd6d3666c88b47172b8efc995523b47346Svetoslav        return false;
10548fec5c9a3e4d78bc4cd175fae05be153ac587afSvet Ganov    }
10648fec5c9a3e4d78bc4cd175fae05be153ac587afSvet Ganov
107a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private FusedPrintersProvider getPrinterProvider() {
108a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        Loader<?> loader = mActivity.getLoaderManager().getLoader(LOADER_ID_PRINTERS_LOADER);
109a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        return (FusedPrintersProvider) loader;
110a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
111a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
112a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private final LoaderCallbacks<List<PrinterInfo>> mLoaderCallbacks =
113a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            new LoaderCallbacks<List<PrinterInfo>>() {
114a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        @Override
115a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public void onLoaderReset(Loader<List<PrinterInfo>> loader) {
116a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            if (loader.getId() == LOADER_ID_PRINTERS_LOADER) {
117a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                mPrinters.clear();
118a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (mOnPrintersChangeListener != null) {
119a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    // Post a message as we are in onLoadFinished and certain operations
120a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    // are not allowed in this callback, such as fragment transactions.
121a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    // Clients should not handle this explicitly.
122a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    mHandler.obtainMessage(MyHandler.MSG_PRINTERS_INVALID,
123a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                            mOnPrintersChangeListener).sendToTarget();
124a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
125a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            }
126a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
127a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
128a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        // LoaderCallbacks#onLoadFinished
129a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        @Override
130a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public void onLoadFinished(Loader<List<PrinterInfo>> loader, List<PrinterInfo> printers) {
131a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            if (loader.getId() == LOADER_ID_PRINTERS_LOADER) {
132a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                mPrinters.clear();
133a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                mPrinters.addAll(printers);
134a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (mOnPrintersChangeListener != null) {
135a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    // Post a message as we are in onLoadFinished and certain operations
136a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    // are not allowed in this callback, such as fragment transactions.
137a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    // Clients should not handle this explicitly.
138a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    SomeArgs args = SomeArgs.obtain();
139a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    args.arg1 = mOnPrintersChangeListener;
140a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    args.arg2 = printers;
141a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    mHandler.obtainMessage(MyHandler.MSG_PRINTERS_CHANGED, args).sendToTarget();
142a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
143a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (!mReady) {
144a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    mReady = true;
145a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    if (mReadyCallback != null) {
146a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        mReadyCallback.run();
147a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    }
148a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
149a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            }
150a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
151a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
152a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        // LoaderCallbacks#onCreateLoader
153a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        @Override
154a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) {
155a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            if (id == LOADER_ID_PRINTERS_LOADER) {
156a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                return new FusedPrintersProvider(mActivity);
157a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            }
158a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            return null;
159a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
160a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    };
161a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
162a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private static final class MyHandler extends Handler {
163a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public static final int MSG_PRINTERS_CHANGED = 0;
164a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public static final int MSG_PRINTERS_INVALID = 1;
165a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
166a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public MyHandler(Looper looper) {
167a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            super(looper, null , false);
168a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
169a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
170a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        @Override
171a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        @SuppressWarnings("unchecked")
172a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public void handleMessage(Message message) {
173a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            switch (message.what) {
174a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                case MSG_PRINTERS_CHANGED: {
175a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    SomeArgs args = (SomeArgs) message.obj;
176a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    OnPrintersChangeListener callback = (OnPrintersChangeListener) args.arg1;
177a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    List<PrinterInfo> printers = (List<PrinterInfo>) args.arg2;
178a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    args.recycle();
179a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    callback.onPrintersChanged(printers);
180a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                } break;
181a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
182a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                case MSG_PRINTERS_INVALID: {
183a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    OnPrintersChangeListener callback = (OnPrintersChangeListener) message.obj;
184a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    callback.onPrintersInvalid();
185a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                } break;
186a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            }
187a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
188a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
189a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav}
190