Merge "Ignore historical printer records for installed services" into klp-dev
diff --git a/core/java/android/print/IPrintManager.aidl b/core/java/android/print/IPrintManager.aidl
index 4044b31..3bd515b 100644
--- a/core/java/android/print/IPrintManager.aidl
+++ b/core/java/android/print/IPrintManager.aidl
@@ -45,6 +45,7 @@
     void removePrintJobStateChangeListener(in IPrintJobStateChangeListener listener,
             int userId);
 
+    List<PrintServiceInfo> getInstalledPrintServices(int userId);
     List<PrintServiceInfo> getEnabledPrintServices(int userId);
 
     void createPrinterDiscoverySession(in IPrinterDiscoveryObserver observer, int userId);
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index a015388..0859fdd 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -289,7 +289,26 @@
                 return enabledServices;
             }
         } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error getting the enalbed print services", re);
+            Log.e(LOG_TAG, "Error getting the enabled print services", re);
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * Gets the list of installed print services.
+     *
+     * @return The installed service list or an empty list.
+     *
+     * @hide
+     */
+    public List<PrintServiceInfo> getInstalledPrintServices() {
+        try {
+            List<PrintServiceInfo> installedServices = mService.getInstalledPrintServices(mUserId);
+            if (installedServices != null) {
+                return installedServices;
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error getting the installed print services", re);
         }
         return Collections.emptyList();
     }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
index 3a1a3c40..65af830 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
@@ -19,13 +19,16 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Loader;
+import android.content.pm.ServiceInfo;
 import android.os.AsyncTask;
 import android.print.PrintManager;
 import android.print.PrinterDiscoverySession;
 import android.print.PrinterDiscoverySession.OnPrintersChangeListener;
 import android.print.PrinterId;
 import android.print.PrinterInfo;
+import android.printservice.PrintServiceInfo;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.Slog;
@@ -46,6 +49,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import libcore.io.IoUtils;
 
@@ -384,6 +388,30 @@
                             + FusedPrintersProvider.this.hashCode());
                 }
 
+                // Ignore printer records whose target services are not installed.
+                PrintManager printManager = (PrintManager) getContext()
+                        .getSystemService(Context.PRINT_SERVICE);
+                List<PrintServiceInfo> services = printManager
+                        .getInstalledPrintServices();
+
+                Set<ComponentName> installedComponents = new ArraySet<ComponentName>();
+                final int installedServiceCount = services.size();
+                for (int i = 0; i < installedServiceCount; i++) {
+                    ServiceInfo serviceInfo = services.get(i).getResolveInfo().serviceInfo;
+                    ComponentName componentName = new ComponentName(
+                            serviceInfo.packageName, serviceInfo.name);
+                    installedComponents.add(componentName);
+                }
+
+                final int printerCount = printers.size();
+                for (int i = printerCount - 1; i >= 0; i--) {
+                    ComponentName printerServiceName = printers.get(i).getId().getServiceName();
+                    if (!installedComponents.contains(printerServiceName.getPackageName())) {
+                        printers.remove(i);
+                    }
+                }
+
+                // Store the filtered list.
                 mHistoricalPrinters = printers;
 
                 // Compute the favorite printers.
diff --git a/services/java/com/android/server/print/PrintManagerService.java b/services/java/com/android/server/print/PrintManagerService.java
index d4583b5..b8e1b04 100644
--- a/services/java/com/android/server/print/PrintManagerService.java
+++ b/services/java/com/android/server/print/PrintManagerService.java
@@ -194,6 +194,21 @@
     }
 
     @Override
+    public List<PrintServiceInfo> getInstalledPrintServices(int userId) {
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return userState.getInstalledPrintServices();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
     public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
             int userId) {
         final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java
index 72acc53..bc70fe3 100644
--- a/services/java/com/android/server/print/UserState.java
+++ b/services/java/com/android/server/print/UserState.java
@@ -205,10 +205,12 @@
         // Add everything else the spooler knows about.
         List<PrintJobInfo> printJobs = mSpooler.getPrintJobInfos(null,
                 PrintJobInfo.STATE_ANY, appId);
-        final int printJobCount = printJobs.size();
-        for (int i = 0; i < printJobCount; i++) {
-            PrintJobInfo printJob = printJobs.get(i);
-            result.put(printJob.getId(), printJob);
+        if (printJobs != null) {
+            final int printJobCount = printJobs.size();
+            for (int i = 0; i < printJobCount; i++) {
+                PrintJobInfo printJob = printJobs.get(i);
+                result.put(printJob.getId(), printJob);
+            }
         }
 
         return new ArrayList<PrintJobInfo>(result.values());
@@ -272,6 +274,12 @@
         }
     }
 
+    public List<PrintServiceInfo> getInstalledPrintServices() {
+        synchronized (mLock) {
+            return mInstalledServices;
+        }
+    }
+
     public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer) {
         synchronized (mLock) {
             throwIfDestroyedLocked();