Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc64fb9c authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by Android (Google) Code Review
Browse files

Merge "Allow Print subsystem to work with services provided by instant app" into pi-dev

parents 09a0c2d5 b3baaab4
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -143,4 +143,21 @@ interface IPrintManager {
    void stopPrinterStateTracking(in PrinterId printerId, int userId);
    void destroyPrinterDiscoverySession(in IPrinterDiscoveryObserver observer,
            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);
}
+2 −0
Original line number Diff line number Diff line
@@ -811,6 +811,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
        List<ResolveInfo> resolvedActivities = getPackageManager()
                .queryIntentActivities(intent, 0);
        if (resolvedActivities.isEmpty()) {
            Log.w(LOG_TAG, "Advanced options activity " + mAdvancedPrintOptionsActivity + " could "
                    + "not be found");
            return;
        }

+55 −2
Original line number Diff line number Diff line
@@ -18,8 +18,12 @@ package com.android.server.print;

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_INSTANT;
import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;

import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.ComponentName;
@@ -36,6 +40,8 @@ import android.os.Bundle;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.UserHandle;
import android.os.UserManager;
import android.print.IPrintDocumentAdapter;
@@ -121,6 +127,13 @@ public final class PrintManagerService extends SystemService {
            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
        public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
                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() {
            return !mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING,
                    Binder.getCallingUserHandle());
@@ -773,7 +826,7 @@ public final class PrintManagerService extends SystemService {

                    List<ResolveInfo> installedServices = mContext.getPackageManager()
                            .queryIntentServicesAsUser(intent,
                                    GET_SERVICES | MATCH_DEBUG_TRIAGED_MISSING,
                                    GET_SERVICES | MATCH_DEBUG_TRIAGED_MISSING | MATCH_INSTANT,
                                    getChangingUserId());

                    return installedServices != null && !installedServices.isEmpty();
@@ -988,7 +1041,7 @@ public final class PrintManagerService extends SystemService {
                return appId;
            }
            final int callingAppId = UserHandle.getAppId(callingUid);
            if (appId == callingAppId || callingAppId == Process.SHELL_UID
            if (appId == callingAppId || callingAppId == SHELL_UID
                    || callingAppId == Process.SYSTEM_UID) {
                return appId;
            }
+112 −0
Original line number Diff line number Diff line
/*
 * 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.");
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -571,8 +571,8 @@ final class RemotePrintService implements DeathRecipient {
        mBinding = true;

        boolean wasBound = mContext.bindServiceAsUser(mIntent, mServiceConnection,
                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
                new UserHandle(mUserId));
                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
                        | Context.BIND_ALLOW_INSTANT, new UserHandle(mUserId));

        if (!wasBound) {
            if (DEBUG) {
Loading