1 /* 2 * Copyright (C) 2016 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.printservice.recommendation; 18 19 import android.content.res.Configuration; 20 import android.net.wifi.WifiManager; 21 import android.printservice.PrintService; 22 import android.printservice.recommendation.RecommendationInfo; 23 import android.printservice.recommendation.RecommendationService; 24 import android.util.Log; 25 26 import com.android.printservice.recommendation.plugin.hp.HPRecommendationPlugin; 27 import com.android.printservice.recommendation.plugin.mdnsFilter.MDNSFilterPlugin; 28 import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig; 29 import com.android.printservice.recommendation.plugin.mopria.MopriaRecommendationPlugin; 30 import com.android.printservice.recommendation.plugin.samsung.SamsungRecommendationPlugin; 31 import com.android.printservice.recommendation.plugin.xerox.XeroxPrintServiceRecommendationPlugin; 32 33 import org.xmlpull.v1.XmlPullParserException; 34 35 import java.io.IOException; 36 import java.net.InetAddress; 37 import java.util.ArrayList; 38 import java.util.List; 39 40 /** 41 * Service that recommends {@link PrintService print services} that might be a good idea to install. 42 */ 43 public class RecommendationServiceImpl extends RecommendationService 44 implements RemotePrintServicePlugin.OnChangedListener { 45 private static final String LOG_TAG = "PrintServiceRecService"; 46 47 /** All registered plugins */ 48 private final ArrayList<RemotePrintServicePlugin> mPlugins = new ArrayList<>(); 49 50 /** Lock to keep multi-cast enabled */ 51 private WifiManager.MulticastLock mMultiCastLock; 52 53 @Override onConnected()54 public void onConnected() { 55 WifiManager wifiManager = getSystemService(WifiManager.class); 56 if (wifiManager != null) { 57 if (mMultiCastLock == null) { 58 mMultiCastLock = wifiManager.createMulticastLock(LOG_TAG); 59 } 60 61 mMultiCastLock.acquire(); 62 } 63 64 try { 65 for (VendorConfig config : VendorConfig.getAllConfigs(this)) { 66 try { 67 mPlugins.add(new RemotePrintServicePlugin(new MDNSFilterPlugin(this, 68 config.name, config.packageName, config.mDNSNames), this, false)); 69 } catch (Exception e) { 70 Log.e(LOG_TAG, "Could not initiate simple MDNS plugin for " + 71 config.packageName, e); 72 } 73 } 74 } catch (IOException | XmlPullParserException e) { 75 throw new RuntimeException("Could not parse vendorconfig", e); 76 } 77 78 try { 79 mPlugins.add(new RemotePrintServicePlugin(new HPRecommendationPlugin(this), this, 80 false)); 81 } catch (Exception e) { 82 Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_hp) + " plugin", 83 e); 84 } 85 86 try { 87 mPlugins.add(new RemotePrintServicePlugin(new MopriaRecommendationPlugin(this), this, 88 true)); 89 } catch (Exception e) { 90 Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_morpia) + 91 " plugin", e); 92 } 93 94 try { 95 mPlugins.add(new RemotePrintServicePlugin(new SamsungRecommendationPlugin(this), this, 96 true)); 97 } catch (Exception e) { 98 Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_samsung) + 99 " plugin", e); 100 } 101 102 try { 103 mPlugins.add(new RemotePrintServicePlugin( 104 new XeroxPrintServiceRecommendationPlugin(this), this, false)); 105 } catch (Exception e) { 106 Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_xerox) + 107 " plugin", e); 108 } 109 110 final int numPlugins = mPlugins.size(); 111 for (int i = 0; i < numPlugins; i++) { 112 try { 113 mPlugins.get(i).start(); 114 } catch (RemotePrintServicePlugin.PluginException e) { 115 Log.e(LOG_TAG, "Could not start plugin", e); 116 } 117 } 118 } 119 120 @Override onDisconnected()121 public void onDisconnected() { 122 final int numPlugins = mPlugins.size(); 123 for (int i = 0; i < numPlugins; i++) { 124 try { 125 mPlugins.get(i).stop(); 126 } catch (RemotePrintServicePlugin.PluginException e) { 127 Log.e(LOG_TAG, "Could not stop plugin", e); 128 } 129 } 130 mPlugins.clear(); 131 132 if (mMultiCastLock != null) { 133 mMultiCastLock.release(); 134 } 135 } 136 137 @Override onConfigurationChanged(Configuration newConfig)138 public void onConfigurationChanged(Configuration newConfig) { 139 // Need to update plugin names as they might be localized 140 onChanged(); 141 } 142 143 @Override onChanged()144 public void onChanged() { 145 ArrayList<RecommendationInfo> recommendations = new ArrayList<>(); 146 147 final int numPlugins = mPlugins.size(); 148 for (int i = 0; i < numPlugins; i++) { 149 RemotePrintServicePlugin plugin = mPlugins.get(i); 150 151 try { 152 List<InetAddress> printers = plugin.getPrinters(); 153 154 if (!printers.isEmpty()) { 155 recommendations.add(new RecommendationInfo(plugin.packageName, 156 getString(plugin.name), printers, plugin.recommendsMultiVendorService)); 157 } 158 } catch (Exception e) { 159 Log.e(LOG_TAG, "Could not read state of plugin for " + plugin.packageName, e); 160 } 161 } 162 163 updateRecommendations(recommendations); 164 } 165 } 166