Implement Policy to disable printing.
This adds a new "isPrintingEnabled" policy (true by default) and hooks it into PrintManagerService. Bug: 64140119 Test: manual Change-Id: Ifb0f6772af51e6185135e9dcf5551e9ef0d88af3
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user