Merge "Allow Print subsystem to work with services provided by instant app" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
cc64fb9c8f
@@ -143,4 +143,21 @@ interface IPrintManager {
|
|||||||
void stopPrinterStateTracking(in PrinterId printerId, int userId);
|
void stopPrinterStateTracking(in PrinterId printerId, int userId);
|
||||||
void destroyPrinterDiscoverySession(in IPrinterDiscoveryObserver observer,
|
void destroyPrinterDiscoverySession(in IPrinterDiscoveryObserver observer,
|
||||||
int userId);
|
int userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the system will bind to print services in intant app.
|
||||||
|
*
|
||||||
|
* @param userId the Id of the user the behavior should be checked for
|
||||||
|
*
|
||||||
|
* @return {@code true} iff the system will bind to print services in instant apps.
|
||||||
|
*/
|
||||||
|
boolean getBindInstantServiceAllowed(int userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if the system will bind to print services in intant app.
|
||||||
|
*
|
||||||
|
* @param userId the Id of the user the behavior should be changed for
|
||||||
|
* @param allows iff {@code true} the system will bind to print services in instant apps
|
||||||
|
*/
|
||||||
|
void setBindInstantServiceAllowed(int userId, boolean allowed);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -811,6 +811,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
|
|||||||
List<ResolveInfo> resolvedActivities = getPackageManager()
|
List<ResolveInfo> resolvedActivities = getPackageManager()
|
||||||
.queryIntentActivities(intent, 0);
|
.queryIntentActivities(intent, 0);
|
||||||
if (resolvedActivities.isEmpty()) {
|
if (resolvedActivities.isEmpty()) {
|
||||||
|
Log.w(LOG_TAG, "Advanced options activity " + mAdvancedPrintOptionsActivity + " could "
|
||||||
|
+ "not be found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,12 @@ package com.android.server.print;
|
|||||||
|
|
||||||
import static android.content.pm.PackageManager.GET_SERVICES;
|
import static android.content.pm.PackageManager.GET_SERVICES;
|
||||||
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
|
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
|
||||||
|
import static android.content.pm.PackageManager.MATCH_INSTANT;
|
||||||
|
import static android.os.Process.ROOT_UID;
|
||||||
|
import static android.os.Process.SHELL_UID;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.UserIdInt;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.admin.DevicePolicyManagerInternal;
|
import android.app.admin.DevicePolicyManagerInternal;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -36,6 +40,8 @@ import android.os.Bundle;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.os.ResultReceiver;
|
||||||
|
import android.os.ShellCallback;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.print.IPrintDocumentAdapter;
|
import android.print.IPrintDocumentAdapter;
|
||||||
@@ -121,6 +127,13 @@ public final class PrintManagerService extends SystemService {
|
|||||||
registerBroadcastReceivers();
|
registerBroadcastReceivers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onShellCommand(FileDescriptor in, FileDescriptor out,
|
||||||
|
FileDescriptor err, String[] args, ShellCallback callback,
|
||||||
|
ResultReceiver resultReceiver) {
|
||||||
|
new PrintShellCommand(this).exec(this, in, out, err, args, callback, resultReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
|
public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
|
||||||
PrintAttributes attributes, String packageName, int appId, int userId) {
|
PrintAttributes attributes, String packageName, int appId, int userId) {
|
||||||
@@ -717,6 +730,46 @@ public final class PrintManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBindInstantServiceAllowed(@UserIdInt int userId) {
|
||||||
|
int callingUid = Binder.getCallingUid();
|
||||||
|
if (callingUid != SHELL_UID && callingUid != ROOT_UID) {
|
||||||
|
throw new SecurityException("Can only be called by uid " + SHELL_UID
|
||||||
|
+ " or " + ROOT_UID);
|
||||||
|
}
|
||||||
|
|
||||||
|
final UserState userState;
|
||||||
|
synchronized (mLock) {
|
||||||
|
userState = getOrCreateUserStateLocked(userId, false);
|
||||||
|
}
|
||||||
|
final long identity = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
return userState.getBindInstantServiceAllowed();
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBindInstantServiceAllowed(@UserIdInt int userId, boolean allowed) {
|
||||||
|
int callingUid = Binder.getCallingUid();
|
||||||
|
if (callingUid != SHELL_UID && callingUid != ROOT_UID) {
|
||||||
|
throw new SecurityException("Can only be called by uid " + SHELL_UID
|
||||||
|
+ " or " + ROOT_UID);
|
||||||
|
}
|
||||||
|
|
||||||
|
final UserState userState;
|
||||||
|
synchronized (mLock) {
|
||||||
|
userState = getOrCreateUserStateLocked(userId, false);
|
||||||
|
}
|
||||||
|
final long identity = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
userState.setBindInstantServiceAllowed(allowed);
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isPrintingEnabled() {
|
private boolean isPrintingEnabled() {
|
||||||
return !mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING,
|
return !mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING,
|
||||||
Binder.getCallingUserHandle());
|
Binder.getCallingUserHandle());
|
||||||
@@ -773,7 +826,7 @@ public final class PrintManagerService extends SystemService {
|
|||||||
|
|
||||||
List<ResolveInfo> installedServices = mContext.getPackageManager()
|
List<ResolveInfo> installedServices = mContext.getPackageManager()
|
||||||
.queryIntentServicesAsUser(intent,
|
.queryIntentServicesAsUser(intent,
|
||||||
GET_SERVICES | MATCH_DEBUG_TRIAGED_MISSING,
|
GET_SERVICES | MATCH_DEBUG_TRIAGED_MISSING | MATCH_INSTANT,
|
||||||
getChangingUserId());
|
getChangingUserId());
|
||||||
|
|
||||||
return installedServices != null && !installedServices.isEmpty();
|
return installedServices != null && !installedServices.isEmpty();
|
||||||
@@ -988,7 +1041,7 @@ public final class PrintManagerService extends SystemService {
|
|||||||
return appId;
|
return appId;
|
||||||
}
|
}
|
||||||
final int callingAppId = UserHandle.getAppId(callingUid);
|
final int callingAppId = UserHandle.getAppId(callingUid);
|
||||||
if (appId == callingAppId || callingAppId == Process.SHELL_UID
|
if (appId == callingAppId || callingAppId == SHELL_UID
|
||||||
|| callingAppId == Process.SYSTEM_UID) {
|
|| callingAppId == Process.SYSTEM_UID) {
|
||||||
return appId;
|
return appId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.server.print;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.ShellCommand;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.print.IPrintManager;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shell command implementation for the print manager service
|
||||||
|
*/
|
||||||
|
final class PrintShellCommand extends ShellCommand {
|
||||||
|
final @NonNull IPrintManager mService;
|
||||||
|
|
||||||
|
PrintShellCommand(@NonNull IPrintManager service) {
|
||||||
|
mService = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onCommand(@Nullable String cmd) {
|
||||||
|
if (cmd == null) {
|
||||||
|
return handleDefaultCommands(cmd);
|
||||||
|
}
|
||||||
|
switch (cmd) {
|
||||||
|
case "get-bind-instant-service-allowed": {
|
||||||
|
return runGetBindInstantServiceAllowed();
|
||||||
|
}
|
||||||
|
case "set-bind-instant-service-allowed": {
|
||||||
|
return runSetBindInstantServiceAllowed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int runGetBindInstantServiceAllowed() {
|
||||||
|
final Integer userId = parseUserId();
|
||||||
|
if (userId == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
getOutPrintWriter().println(
|
||||||
|
Boolean.toString(mService.getBindInstantServiceAllowed(userId)));
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int runSetBindInstantServiceAllowed() {
|
||||||
|
final Integer userId = parseUserId();
|
||||||
|
if (userId == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
final String allowed = getNextArgRequired();
|
||||||
|
if (allowed == null) {
|
||||||
|
getErrPrintWriter().println("Error: no true/false specified");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mService.setBindInstantServiceAllowed(userId, Boolean.parseBoolean(allowed));
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable Integer parseUserId() {
|
||||||
|
final String option = getNextOption();
|
||||||
|
if (option != null) {
|
||||||
|
if (option.equals("--user")) {
|
||||||
|
return UserHandle.parseUserArg(getNextArgRequired());
|
||||||
|
} else {
|
||||||
|
getErrPrintWriter().println("Unknown option: " + option);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UserHandle.USER_SYSTEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onHelp() {
|
||||||
|
PrintWriter pw = getOutPrintWriter();
|
||||||
|
pw.println("Print service commands:");
|
||||||
|
pw.println(" help");
|
||||||
|
pw.println(" Print this help text.");
|
||||||
|
pw.println(" set-bind-instant-service-allowed [--user <USER_ID>] true|false ");
|
||||||
|
pw.println(" Set whether binding to print services provided by instant apps is "
|
||||||
|
+ "allowed.");
|
||||||
|
pw.println(" get-bind-instant-service-allowed [--user <USER_ID>]");
|
||||||
|
pw.println(" Get whether binding to print services provided by instant apps is "
|
||||||
|
+ "allowed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -571,8 +571,8 @@ final class RemotePrintService implements DeathRecipient {
|
|||||||
mBinding = true;
|
mBinding = true;
|
||||||
|
|
||||||
boolean wasBound = mContext.bindServiceAsUser(mIntent, mServiceConnection,
|
boolean wasBound = mContext.bindServiceAsUser(mIntent, mServiceConnection,
|
||||||
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
|
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
|
||||||
new UserHandle(mUserId));
|
| Context.BIND_ALLOW_INSTANT, new UserHandle(mUserId));
|
||||||
|
|
||||||
if (!wasBound) {
|
if (!wasBound) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.server.print;
|
|||||||
import static android.content.pm.PackageManager.GET_META_DATA;
|
import static android.content.pm.PackageManager.GET_META_DATA;
|
||||||
import static android.content.pm.PackageManager.GET_SERVICES;
|
import static android.content.pm.PackageManager.GET_SERVICES;
|
||||||
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
|
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
|
||||||
|
import static android.content.pm.PackageManager.MATCH_INSTANT;
|
||||||
|
|
||||||
import static com.android.internal.print.DumpUtils.writePrintJobInfo;
|
import static com.android.internal.print.DumpUtils.writePrintJobInfo;
|
||||||
import static com.android.internal.print.DumpUtils.writePrinterId;
|
import static com.android.internal.print.DumpUtils.writePrinterId;
|
||||||
@@ -155,6 +156,11 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks,
|
|||||||
*/
|
*/
|
||||||
private RemotePrintServiceRecommendationService mPrintServiceRecommendationsService;
|
private RemotePrintServiceRecommendationService mPrintServiceRecommendationsService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can services from instant apps be bound? (usually disabled, only used by testing)
|
||||||
|
*/
|
||||||
|
private boolean mIsInstantServiceAllowed;
|
||||||
|
|
||||||
public UserState(Context context, int userId, Object lock, boolean lowPriority) {
|
public UserState(Context context, int userId, Object lock, boolean lowPriority) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mUserId = userId;
|
mUserId = userId;
|
||||||
@@ -872,9 +878,14 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks,
|
|||||||
private void readInstalledPrintServicesLocked() {
|
private void readInstalledPrintServicesLocked() {
|
||||||
Set<PrintServiceInfo> tempPrintServices = new HashSet<PrintServiceInfo>();
|
Set<PrintServiceInfo> tempPrintServices = new HashSet<PrintServiceInfo>();
|
||||||
|
|
||||||
|
int queryIntentFlags = GET_SERVICES | GET_META_DATA | MATCH_DEBUG_TRIAGED_MISSING;
|
||||||
|
|
||||||
|
if (mIsInstantServiceAllowed) {
|
||||||
|
queryIntentFlags |= MATCH_INSTANT;
|
||||||
|
}
|
||||||
|
|
||||||
List<ResolveInfo> installedServices = mContext.getPackageManager()
|
List<ResolveInfo> installedServices = mContext.getPackageManager()
|
||||||
.queryIntentServicesAsUser(mQueryIntent,
|
.queryIntentServicesAsUser(mQueryIntent, queryIntentFlags, mUserId);
|
||||||
GET_SERVICES | GET_META_DATA | MATCH_DEBUG_TRIAGED_MISSING, mUserId);
|
|
||||||
|
|
||||||
final int installedCount = installedServices.size();
|
final int installedCount = installedServices.size();
|
||||||
for (int i = 0, count = installedCount; i < count; i++) {
|
for (int i = 0, count = installedCount; i < count; i++) {
|
||||||
@@ -1185,6 +1196,18 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getBindInstantServiceAllowed() {
|
||||||
|
return mIsInstantServiceAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBindInstantServiceAllowed(boolean allowed) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mIsInstantServiceAllowed = allowed;
|
||||||
|
|
||||||
|
updateIfNeededLocked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private abstract class PrintJobStateChangeListenerRecord implements DeathRecipient {
|
private abstract class PrintJobStateChangeListenerRecord implements DeathRecipient {
|
||||||
@NonNull final IPrintJobStateChangeListener listener;
|
@NonNull final IPrintJobStateChangeListener listener;
|
||||||
final int appId;
|
final int appId;
|
||||||
|
|||||||
Reference in New Issue
Block a user