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 17 package com.android.printspooler.ui; 18 19 import android.app.Activity; 20 import android.app.LoaderManager.LoaderCallbacks; 21 import android.content.Loader; 22 import android.os.Bundle; 23 import android.os.Handler; 24 import android.os.Looper; 25 import android.os.Message; 26 import android.print.PrinterId; 27 import android.print.PrinterInfo; 28 import com.android.internal.os.SomeArgs; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 public class PrinterRegistry { 34 35 private static final int LOADER_ID_PRINTERS_LOADER = 1; 36 37 private final Activity mActivity; 38 39 private final List<PrinterInfo> mPrinters = new ArrayList<>(); 40 41 private final Runnable mReadyCallback; 42 43 private final Handler mHandler; 44 45 private boolean mReady; 46 47 private OnPrintersChangeListener mOnPrintersChangeListener; 48 49 public interface OnPrintersChangeListener { onPrintersChanged(List<PrinterInfo> printers)50 public void onPrintersChanged(List<PrinterInfo> printers); onPrintersInvalid()51 public void onPrintersInvalid(); 52 } 53 PrinterRegistry(Activity activity, Runnable readyCallback)54 public PrinterRegistry(Activity activity, Runnable readyCallback) { 55 mActivity = activity; 56 mReadyCallback = readyCallback; 57 mHandler = new MyHandler(activity.getMainLooper()); 58 activity.getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, 59 null, mLoaderCallbacks); 60 } 61 setOnPrintersChangeListener(OnPrintersChangeListener listener)62 public void setOnPrintersChangeListener(OnPrintersChangeListener listener) { 63 mOnPrintersChangeListener = listener; 64 } 65 getPrinters()66 public List<PrinterInfo> getPrinters() { 67 return mPrinters; 68 } 69 addHistoricalPrinter(PrinterInfo printer)70 public void addHistoricalPrinter(PrinterInfo printer) { 71 FusedPrintersProvider provider = getPrinterProvider(); 72 if (provider != null) { 73 getPrinterProvider().addHistoricalPrinter(printer); 74 } 75 } 76 forgetFavoritePrinter(PrinterId printerId)77 public void forgetFavoritePrinter(PrinterId printerId) { 78 FusedPrintersProvider provider = getPrinterProvider(); 79 if (provider != null) { 80 provider.forgetFavoritePrinter(printerId); 81 } 82 } 83 isFavoritePrinter(PrinterId printerId)84 public boolean isFavoritePrinter(PrinterId printerId) { 85 FusedPrintersProvider provider = getPrinterProvider(); 86 if (provider != null) { 87 return provider.isFavoritePrinter(printerId); 88 } 89 return false; 90 } 91 setTrackedPrinter(PrinterId printerId)92 public void setTrackedPrinter(PrinterId printerId) { 93 FusedPrintersProvider provider = getPrinterProvider(); 94 if (provider != null) { 95 provider.setTrackedPrinter(printerId); 96 } 97 } 98 areHistoricalPrintersLoaded()99 public boolean areHistoricalPrintersLoaded() { 100 FusedPrintersProvider provider = getPrinterProvider(); 101 if (provider != null) { 102 return getPrinterProvider().areHistoricalPrintersLoaded(); 103 } 104 return false; 105 } 106 getPrinterProvider()107 private FusedPrintersProvider getPrinterProvider() { 108 Loader<?> loader = mActivity.getLoaderManager().getLoader(LOADER_ID_PRINTERS_LOADER); 109 return (FusedPrintersProvider) loader; 110 } 111 112 private final LoaderCallbacks<List<PrinterInfo>> mLoaderCallbacks = 113 new LoaderCallbacks<List<PrinterInfo>>() { 114 @Override 115 public void onLoaderReset(Loader<List<PrinterInfo>> loader) { 116 if (loader.getId() == LOADER_ID_PRINTERS_LOADER) { 117 mPrinters.clear(); 118 if (mOnPrintersChangeListener != null) { 119 // Post a message as we are in onLoadFinished and certain operations 120 // are not allowed in this callback, such as fragment transactions. 121 // Clients should not handle this explicitly. 122 mHandler.obtainMessage(MyHandler.MSG_PRINTERS_INVALID, 123 mOnPrintersChangeListener).sendToTarget(); 124 } 125 } 126 } 127 128 // LoaderCallbacks#onLoadFinished 129 @Override 130 public void onLoadFinished(Loader<List<PrinterInfo>> loader, List<PrinterInfo> printers) { 131 if (loader.getId() == LOADER_ID_PRINTERS_LOADER) { 132 mPrinters.clear(); 133 mPrinters.addAll(printers); 134 if (mOnPrintersChangeListener != null) { 135 // Post a message as we are in onLoadFinished and certain operations 136 // are not allowed in this callback, such as fragment transactions. 137 // Clients should not handle this explicitly. 138 SomeArgs args = SomeArgs.obtain(); 139 args.arg1 = mOnPrintersChangeListener; 140 args.arg2 = printers; 141 mHandler.obtainMessage(MyHandler.MSG_PRINTERS_CHANGED, args).sendToTarget(); 142 } 143 if (!mReady) { 144 mReady = true; 145 if (mReadyCallback != null) { 146 mReadyCallback.run(); 147 } 148 } 149 } 150 } 151 152 // LoaderCallbacks#onCreateLoader 153 @Override 154 public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) { 155 if (id == LOADER_ID_PRINTERS_LOADER) { 156 return new FusedPrintersProvider(mActivity); 157 } 158 return null; 159 } 160 }; 161 162 private static final class MyHandler extends Handler { 163 public static final int MSG_PRINTERS_CHANGED = 0; 164 public static final int MSG_PRINTERS_INVALID = 1; 165 MyHandler(Looper looper)166 public MyHandler(Looper looper) { 167 super(looper, null , false); 168 } 169 170 @Override 171 @SuppressWarnings("unchecked") handleMessage(Message message)172 public void handleMessage(Message message) { 173 switch (message.what) { 174 case MSG_PRINTERS_CHANGED: { 175 SomeArgs args = (SomeArgs) message.obj; 176 OnPrintersChangeListener callback = (OnPrintersChangeListener) args.arg1; 177 List<PrinterInfo> printers = (List<PrinterInfo>) args.arg2; 178 args.recycle(); 179 callback.onPrintersChanged(printers); 180 } break; 181 182 case MSG_PRINTERS_INVALID: { 183 OnPrintersChangeListener callback = (OnPrintersChangeListener) message.obj; 184 callback.onPrintersInvalid(); 185 } break; 186 } 187 } 188 } 189 } 190