1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  * Copyright (C) 2016 Mopria Alliance, Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.bips;
19 
20 import android.content.Context;
21 import android.content.pm.PackageInfo;
22 import android.content.pm.PackageManager;
23 import android.net.wifi.WifiManager;
24 import android.os.Handler;
25 import android.printservice.PrintJob;
26 import android.printservice.PrintService;
27 import android.printservice.PrinterDiscoverySession;
28 import android.util.Log;
29 
30 import com.android.bips.discovery.Discovery;
31 import com.android.bips.discovery.ManualDiscovery;
32 import com.android.bips.discovery.MdnsDiscovery;
33 import com.android.bips.discovery.MultiDiscovery;
34 import com.android.bips.ipp.Backend;
35 import com.android.bips.ipp.CapabilitiesCache;
36 import com.android.bips.util.WifiMonitor;
37 
38 import java.lang.ref.WeakReference;
39 
40 public class BuiltInPrintService extends PrintService {
41     private static final String TAG = BuiltInPrintService.class.getSimpleName();
42     private static final boolean DEBUG = false;
43 
44     // Present because local activities can bind, but cannot access this object directly
45     private static WeakReference<BuiltInPrintService> sInstance;
46 
47     private Discovery mDiscovery;
48     private ManualDiscovery mManualDiscovery;
49     private CapabilitiesCache mCapabilitiesCache;
50     private JobQueue mJobQueue;
51     private Handler mMainHandler;
52     private Backend mBackend;
53     private WifiManager.WifiLock mWifiLock;
54 
55     /**
56      * Return the current print service instance, if running
57      */
getInstance()58     public static BuiltInPrintService getInstance() {
59         return sInstance == null ? null : sInstance.get();
60     }
61 
62     @Override
onCreate()63     public void onCreate() {
64         if (DEBUG) {
65             try {
66                 PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
67                 String version = pInfo.versionName;
68                 Log.d(TAG, "onCreate() " + version);
69             } catch (PackageManager.NameNotFoundException ignored) {
70             }
71         }
72         super.onCreate();
73 
74         sInstance = new WeakReference<>(this);
75         mBackend = new Backend(this);
76         mCapabilitiesCache = new CapabilitiesCache(this, mBackend,
77                 CapabilitiesCache.DEFAULT_MAX_CONCURRENT);
78         mManualDiscovery = new ManualDiscovery(this);
79         mDiscovery = new MultiDiscovery(this, new WifiMonitor.Factory(), new MdnsDiscovery(this),
80                 mManualDiscovery);
81         mJobQueue = new JobQueue();
82         mMainHandler = new Handler(getMainLooper());
83         WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
84         mWifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG);
85     }
86 
87     @Override
onDestroy()88     public void onDestroy() {
89         if (DEBUG) Log.d(TAG, "onDestroy()");
90         mCapabilitiesCache.close();
91         mManualDiscovery.close();
92         mBackend.close();
93         unlockWifi();
94         sInstance = null;
95         mMainHandler.removeCallbacksAndMessages(null);
96         super.onDestroy();
97     }
98 
99     @Override
onCreatePrinterDiscoverySession()100     protected PrinterDiscoverySession onCreatePrinterDiscoverySession() {
101         if (DEBUG) Log.d(TAG, "onCreatePrinterDiscoverySession");
102         return new LocalDiscoverySession(this);
103     }
104 
105     @Override
onPrintJobQueued(PrintJob printJob)106     protected void onPrintJobQueued(PrintJob printJob) {
107         if (DEBUG) Log.d(TAG, "onPrintJobQueued");
108         if (WifiMonitor.isConnected(this)) {
109             mJobQueue.print(new LocalPrintJob(this, mBackend, printJob));
110         } else {
111             printJob.fail(getString(R.string.wifi_not_connected));
112         }
113     }
114 
115     @Override
onRequestCancelPrintJob(PrintJob printJob)116     protected void onRequestCancelPrintJob(PrintJob printJob) {
117         if (DEBUG) Log.d(TAG, "onRequestCancelPrintJob");
118         mJobQueue.cancel(printJob.getId());
119     }
120 
121     /**
122      * Return the global discovery object
123      */
getDiscovery()124     Discovery getDiscovery() {
125         return mDiscovery;
126     }
127 
getManualDiscovery()128     public ManualDiscovery getManualDiscovery() {
129         return mManualDiscovery;
130     }
131 
132     /**
133      * Return the global Printer Capabilities cache
134      */
getCapabilitiesCache()135     public CapabilitiesCache getCapabilitiesCache() {
136         return mCapabilitiesCache;
137     }
138 
139     /** Return the main handler for running on main UI */
getMainHandler()140     public Handler getMainHandler() {
141         return mMainHandler;
142     }
143 
144     /** Prevent Wi-Fi from going to sleep until {@link #unlockWifi} is called */
lockWifi()145     public void lockWifi() {
146         if (!mWifiLock.isHeld()) {
147             mWifiLock.acquire();
148         }
149     }
150 
151     /** Allow Wi-Fi to be disabled during sleep modes. */
unlockWifi()152     public void unlockWifi() {
153         if (mWifiLock.isHeld()) {
154             mWifiLock.release();
155         }
156     }
157 }