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