From b7b880315a81073a724db2dbba1ce9b7e94dfdcd Mon Sep 17 00:00:00 2001 From: Erik Wolsheimer Date: Wed, 9 Mar 2022 20:40:25 -0800 Subject: [PATCH] Add method PrintManager#isPrintServiceEnabled(ComponentName) Bug: 180582919 Test: atest FrameworksCoreTests Change-Id: I2f7e87d9e56f3abc22c04eee3e0863d5de48a9f9 --- core/api/current.txt | 1 + core/java/android/print/IPrintManager.aidl | 9 +++++++ core/java/android/print/PrintManager.java | 19 +++++++++++++ .../print/IPrintManagerParametersTest.java | 14 ++++++++++ .../server/print/PrintManagerService.java | 27 +++++++++++++++++++ .../com/android/server/print/UserState.java | 10 ++++++- 6 files changed, 79 insertions(+), 1 deletion(-) diff --git a/core/api/current.txt b/core/api/current.txt index 19ffd36eb47a..6c0b18f82cf8 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -33335,6 +33335,7 @@ package android.print { public final class PrintManager { method @NonNull public java.util.List getPrintJobs(); + method public boolean isPrintServiceEnabled(@NonNull android.content.ComponentName); method @NonNull public android.print.PrintJob print(@NonNull String, @NonNull android.print.PrintDocumentAdapter, @Nullable android.print.PrintAttributes); } diff --git a/core/java/android/print/IPrintManager.aidl b/core/java/android/print/IPrintManager.aidl index d3d38744a1a9..da9d23b5303a 100644 --- a/core/java/android/print/IPrintManager.aidl +++ b/core/java/android/print/IPrintManager.aidl @@ -90,6 +90,15 @@ interface IPrintManager { */ void setPrintServiceEnabled(in ComponentName service, boolean isEnabled, int userId); + /** + * Checks whether the given print service is enabled. + * + * @param service the service to check + * @param userId the id of the user requesting the check + * @return whether the given print service is enabled + */ + boolean isPrintServiceEnabled(in ComponentName service, int userId); + /** * Listen for changes to the print service recommendations. * diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index 9abce5d46ac6..a5e2f33d4418 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -784,6 +784,25 @@ public final class PrintManager { } } + /** + * Checks whether a given print service is enabled. The provided service must share UID + * with the calling package, otherwise a {@link SecurityException} is thrown. + * + * @return true if the given print service is enabled + */ + public boolean isPrintServiceEnabled(@NonNull ComponentName service) { + if (mService == null) { + Log.w(LOG_TAG, "Feature android.software.print not available"); + return false; + } + try { + return mService.isPrintServiceEnabled(service, mUserId); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error sampling enabled/disabled " + service, re); + return false; + } + } + /** * @hide */ diff --git a/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java index 4dd4d1c7bd12..3766cd4ebab1 100644 --- a/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java +++ b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java @@ -485,6 +485,20 @@ public class IPrintManagerParametersTest extends BasePrintTest { // Cannot test bad user Id as these tests are allowed to call across users } + /** + * test IPrintManager.isPrintServiceEnabled + */ + @MediumTest + @Test + @NoActivity + public void testIsPrintServiceEnabled() throws Throwable { + assertException(() -> mIPrintManager.isPrintServiceEnabled(new ComponentName("bad", "name"), + mUserId), SecurityException.class); + + assertException(() -> mIPrintManager.isPrintServiceEnabled(null, mUserId), + SecurityException.class); + } + /** * test IPrintManager.addPrintServiceRecommendationsChangeListener */ diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java index 1cdcbd87c1f5..66524edf61ed 100644 --- a/services/print/java/com/android/server/print/PrintManagerService.java +++ b/services/print/java/com/android/server/print/PrintManagerService.java @@ -369,6 +369,33 @@ public final class PrintManagerService extends SystemService { } } + @Override + public boolean isPrintServiceEnabled(ComponentName service, int userId) { + final String[] packages = mContext.getPackageManager().getPackagesForUid( + Binder.getCallingUid()); + boolean matchCalling = false; + for (int i = 0; i < packages.length; i++) { + if (packages[i].equals(service.getPackageName())) { + matchCalling = true; + break; + } + } + if (!matchCalling) { + // Do not reveal any information about other package services. + throw new SecurityException("PrintService does not share UID with caller."); + } + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + // Only the current group members can check print services. + if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { + return false; + } + userState = getOrCreateUserStateLocked(resolvedUserId, false); + } + return userState.isPrintServiceEnabled(service); + } + @Override public List getPrintServiceRecommendations(int userId) { mContext.enforceCallingOrSelfPermission( diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java index b93c519ec8e4..774f62d44045 100644 --- a/services/print/java/com/android/server/print/UserState.java +++ b/services/print/java/com/android/server/print/UserState.java @@ -63,7 +63,6 @@ import android.print.PrinterInfo; import android.printservice.PrintServiceInfo; import android.printservice.recommendation.IRecommendationsChangeListener; import android.printservice.recommendation.RecommendationInfo; -import android.provider.DocumentsContract; import android.provider.Settings; import android.service.print.CachedPrintJobProto; import android.service.print.InstalledPrintServiceProto; @@ -438,6 +437,15 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks, } } + public boolean isPrintServiceEnabled(@NonNull ComponentName serviceName) { + synchronized (mLock) { + if (mDisabledServices.contains(serviceName)) { + return false; + } + return true; + } + } + /** * @return The currently known print service recommendations */