summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java46
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl4
-rw-r--r--core/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java15
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java103
-rw-r--r--services/print/java/com/android/server/print/PrintManagerService.java33
7 files changed, 203 insertions, 2 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9329d56a8de9..0be55642d4cf 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -9197,4 +9197,50 @@ public class DevicePolicyManager {
throw re.rethrowFromSystemServer();
}
}
+
+ /**
+ * Allows/disallows printing.
+ *
+ * @param admin which {@link DeviceAdminReceiver} this request is associated with.
+ * @param enabled whether printing should be allowed or not.
+ * @throws SecurityException if {@code admin} is neither device, nor profile owner.
+ * @hide
+ */
+ public void setPrintingEnabled(@NonNull ComponentName admin, boolean enabled) {
+ try {
+ mService.setPrintingEnabled(admin, enabled);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns whether printing is enabled for current user.
+ *
+ * @return {@code true} iff printing is enabled.
+ * @hide
+ */
+ public boolean isPrintingEnabled() {
+ try {
+ return mService.isPrintingEnabled();
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns error message to be displayed when printing is disabled.
+ *
+ * Used only by PrintService.
+ * @return Localized error message.
+ * @throws SecurityException if caller is not system.
+ * @hide
+ */
+ public CharSequence getPrintingDisabledReason() {
+ try {
+ return mService.getPrintingDisabledReason();
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index eac7f7ed4b3e..d2a2be7bbcb5 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -396,4 +396,8 @@ interface IDevicePolicyManager {
void setEndUserSessionMessage(in ComponentName admin, in CharSequence endUserSessionMessage);
CharSequence getStartUserSessionMessage(in ComponentName admin);
CharSequence getEndUserSessionMessage(in ComponentName admin);
+
+ void setPrintingEnabled(in ComponentName admin, boolean enabled);
+ boolean isPrintingEnabled();
+ CharSequence getPrintingDisabledReason();
}
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b2fa294f77be..10c883e3af0e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -379,6 +379,9 @@
<string name="factory_reset_message">The admin app can\'t be used. Your device will now be
erased.\n\nIf you have questions, contact your organization's admin.</string>
+ <!-- A toast message displayed when printing is attempted but disabled by policy. -->
+ <string name="printing_disabled_by">Printing disabled by <xliff:g id="owner_app">%s</xliff:g>.</string>
+
<!-- Display name for any time a piece of data refers to the owner of the phone. For example, this could be used in place of the phone's phone number. -->
<string name="me">Me</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6e33648b6f14..f572d67b8862 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -878,6 +878,7 @@
<java-symbol type="string" name="preposition_for_time" />
<java-symbol type="string" name="print_service_installed_title" />
<java-symbol type="string" name="print_service_installed_message" />
+ <java-symbol type="string" name="printing_disabled_by" />
<java-symbol type="string" name="progress_erasing" />
<java-symbol type="string" name="mobile_provisioning_apn" />
<java-symbol type="string" name="mobile_provisioning_url" />
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index 384b416b0201..99275e88a242 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -126,4 +126,19 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
public String getEndUserSessionMessage(ComponentName admin) {
return null;
}
+
+ @Override
+ public void setPrintingEnabled(ComponentName admin, boolean enabled) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isPrintingEnabled() {
+ return true;
+ }
+
+ @Override
+ public CharSequence getPrintingDisabledReason() {
+ return null;
+ }
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cb4f5c1177df..956b185be19e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -74,6 +74,7 @@ import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
+import android.app.ActivityThread;
import android.app.AlarmManager;
import android.app.AppGlobals;
import android.app.IActivityManager;
@@ -285,6 +286,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
private static final String TAG_PASSWORD_VALIDITY = "password-validity";
+ private static final String TAG_PRINTING_ENABLED = "printing-enabled";
+
private static final int REQUEST_EXPIRE_PASSWORD = 5571;
private static final long MS_PER_DAY = TimeUnit.DAYS.toMillis(1);
@@ -589,6 +592,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
long mPasswordTokenHandle = 0;
+ boolean mPrintingEnabled = true;
+
public DevicePolicyData(int userHandle) {
mUserHandle = userHandle;
}
@@ -2880,6 +2885,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
out.endTag(null, TAG_CURRENT_INPUT_METHOD_SET);
}
+ if (!policy.mPrintingEnabled) {
+ out.startTag(null, TAG_PRINTING_ENABLED);
+ out.attribute(null, ATTR_VALUE, Boolean.toString(policy.mPrintingEnabled));
+ out.endTag(null, TAG_PRINTING_ENABLED);
+ }
+
for (final String cert : policy.mOwnerInstalledCaCerts) {
out.startTag(null, TAG_OWNER_INSTALLED_CA_CERT);
out.attribute(null, ATTR_ALIAS, cert);
@@ -3098,6 +3109,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
policy.mCurrentInputMethodSet = true;
} else if (TAG_OWNER_INSTALLED_CA_CERT.equals(tag)) {
policy.mOwnerInstalledCaCerts.add(parser.getAttributeValue(null, ATTR_ALIAS));
+ } else if (TAG_PRINTING_ENABLED.equals(tag)) {
+ String enabled = parser.getAttributeValue(null, ATTR_VALUE);
+ policy.mPrintingEnabled = Boolean.toString(true).equals(enabled);
} else {
Slog.w(LOG_TAG, "Unknown tag: " + tag);
XmlUtils.skipCurrentTag(parser);
@@ -12274,4 +12288,93 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return deviceOwner.endUserSessionMessage;
}
}
+
+ private boolean hasPrinting() {
+ return mInjector.getPackageManager().hasSystemFeature(PackageManager.FEATURE_PRINTING);
+ }
+
+ @Override
+ public void setPrintingEnabled(ComponentName admin, boolean enabled) {
+ if (!mHasFeature || !hasPrinting()) {
+ return;
+ }
+ Preconditions.checkNotNull(admin, "Admin cannot be null.");
+ enforceProfileOrDeviceOwner(admin);
+ synchronized (this) {
+ final int userHandle = mInjector.userHandleGetCallingUserId();
+ DevicePolicyData policy = getUserData(userHandle);
+ if (policy.mPrintingEnabled != enabled) {
+ policy.mPrintingEnabled = enabled;
+ saveSettingsLocked(userHandle);
+ }
+ }
+ }
+
+ /**
+ * Returns whether printing is enabled for current user.
+ * @hide
+ */
+ @Override
+ public boolean isPrintingEnabled() {
+ if (!hasPrinting()) {
+ return false;
+ }
+ if (!mHasFeature) {
+ return true;
+ }
+ synchronized (this) {
+ final int userHandle = mInjector.userHandleGetCallingUserId();
+ DevicePolicyData policy = getUserData(userHandle);
+ return policy.mPrintingEnabled;
+ }
+ }
+
+ /**
+ * Returns text of error message if printing is disabled.
+ * Only to be called by Print Service.
+ * @hide
+ */
+ @Override
+ public CharSequence getPrintingDisabledReason() {
+ if (!hasPrinting() || !mHasFeature) {
+ Log.e(LOG_TAG, "no printing or no management");
+ return null;
+ }
+ synchronized (this) {
+ final int userHandle = mInjector.userHandleGetCallingUserId();
+ DevicePolicyData policy = getUserData(userHandle);
+ if (policy.mPrintingEnabled) {
+ Log.e(LOG_TAG, "printing is enabled");
+ return null;
+ }
+ String ownerPackage = mOwners.getProfileOwnerPackage(userHandle);
+ if (ownerPackage == null) {
+ ownerPackage = mOwners.getDeviceOwnerPackageName();
+ }
+ PackageManager pm = mInjector.getPackageManager();
+ PackageInfo packageInfo;
+ try {
+ packageInfo = pm.getPackageInfo(ownerPackage, 0);
+ } catch (NameNotFoundException e) {
+ Log.e(LOG_TAG, "getPackageInfo error", e);
+ return null;
+ }
+ if (packageInfo == null) {
+ Log.e(LOG_TAG, "packageInfo is inexplicably null");
+ return null;
+ }
+ ApplicationInfo appInfo = packageInfo.applicationInfo;
+ if (appInfo == null) {
+ Log.e(LOG_TAG, "appInfo is inexplicably null");
+ return null;
+ }
+ CharSequence appLabel = pm.getApplicationLabel(appInfo);
+ if (appLabel == null) {
+ Log.e(LOG_TAG, "appLabel is inexplicably null");
+ return null;
+ }
+ return ((Context) ActivityThread.currentActivityThread().getSystemUiContext())
+ .getResources().getString(R.string.printing_disabled_by, appLabel);
+ }
+ }
}
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index cd4e8f977d60..89a5fe1b82c7 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
import android.annotation.NonNull;
import android.app.ActivityManager;
+import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -32,6 +33,7 @@ import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -54,6 +56,7 @@ import android.service.print.PrintServiceDumpProto;
import android.util.Log;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
+import android.widget.Toast;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
@@ -110,9 +113,12 @@ public final class PrintManagerService extends SystemService {
private final SparseArray<UserState> mUserStates = new SparseArray<>();
+ private final DevicePolicyManager mDpc;
+
PrintManagerImpl(Context context) {
mContext = context;
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ mDpc = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
registerContentObservers();
registerBroadcastReceivers();
}
@@ -120,8 +126,26 @@ public final class PrintManagerService extends SystemService {
@Override
public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
PrintAttributes attributes, String packageName, int appId, int userId) {
- printJobName = Preconditions.checkStringNotEmpty(printJobName);
adapter = Preconditions.checkNotNull(adapter);
+ if (!isPrintingEnabled()) {
+ final CharSequence disabledMessage = mDpc.getPrintingDisabledReason();
+ if (disabledMessage != null) {
+ Toast.makeText(mContext, Looper.getMainLooper(), disabledMessage,
+ Toast.LENGTH_LONG).show();
+ }
+ try {
+ adapter.start();
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error calling IPrintDocumentAdapter.start()");
+ }
+ try {
+ adapter.finish();
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error calling IPrintDocumentAdapter.finish()");
+ }
+ return null;
+ }
+ printJobName = Preconditions.checkStringNotEmpty(printJobName);
packageName = Preconditions.checkStringNotEmpty(packageName);
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
@@ -240,7 +264,8 @@ public final class PrintManagerService extends SystemService {
@Override
public void restartPrintJob(PrintJobId printJobId, int appId, int userId) {
- if (printJobId == null) {
+ if (printJobId == null || !isPrintingEnabled()) {
+ // if printing is disabled the state just remains "failed".
return;
}
@@ -685,6 +710,10 @@ public final class PrintManagerService extends SystemService {
}
}
+ private boolean isPrintingEnabled() {
+ return mDpc == null || mDpc.isPrintingEnabled();
+ }
+
private void dump(@NonNull DualDumpOutputStream dumpStream,
@NonNull ArrayList<UserState> userStatesToDump) {
final int userStateCount = userStatesToDump.size();