diff options
6 files changed, 79 insertions, 1 deletions
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<android.print.PrintJob> 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 @@ -91,6 +91,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. * * @param listener the listener to add 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 @@ -785,6 +785,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 */ public static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub 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 @@ -486,6 +486,20 @@ public class IPrintManagerParametersTest extends BasePrintTest { } /** + * 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 */ @MediumTest 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 @@ -370,6 +370,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<RecommendationInfo> getPrintServiceRecommendations(int userId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS, null); 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 */ |