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

Commit 33da7043 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add shell command to get slice permissions" into pi-dev

parents 7830cd82 7f01f3b6
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -127,6 +127,10 @@ public abstract class SliceProvider extends ContentProvider {
     * @hide
     */
    public static final String METHOD_GET_DESCENDANTS = "get_descendants";
    /**
     * @hide
     */
    public static final String METHOD_GET_PERMISSIONS = "get_permissions";
    /**
     * @hide
     */
@@ -147,6 +151,10 @@ public abstract class SliceProvider extends ContentProvider {
     * @hide
     */
    public static final String EXTRA_PROVIDER_PKG = "provider_pkg";
    /**
     * @hide
     */
    public static final String EXTRA_RESULT = "result";

    private static final boolean DEBUG = false;

@@ -392,6 +400,13 @@ public abstract class SliceProvider extends ContentProvider {
            b.putParcelableArrayList(EXTRA_SLICE_DESCENDANTS,
                    new ArrayList<>(handleGetDescendants(uri)));
            return b;
        } else if (method.equals(METHOD_GET_PERMISSIONS)) {
            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
                throw new SecurityException("Only the system can get permissions");
            }
            Bundle b = new Bundle();
            b.putStringArray(EXTRA_RESULT, mAutoGrantPermissions);
            return b;
        }
        return super.call(method, arg, extras);
    }
+18 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -49,6 +50,8 @@ import android.os.IBinder;
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.util.ArrayMap;
import android.util.Slog;
@@ -69,6 +72,7 @@ import org.xmlpull.v1.XmlSerializer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -320,6 +324,12 @@ public class SliceManagerService extends ISliceManager.Stub {
        }
    }

    @Override
    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
            String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
        new SliceShellCommand(this).exec(this, in, out, err, args, callback, resultReceiver);
    }

    ///  ----- internal code -----
    private void enforceOwner(String pkg, Uri uri, int user) {
        if (!Objects.equals(getProviderPkg(uri, user), pkg) || pkg == null) {
@@ -541,6 +551,14 @@ public class SliceManagerService extends ISliceManager.Stub {
        }
    };

    public String[] getAllPackagesGranted(String authority) {
        String pkg = getProviderPkg(new Uri.Builder()
                .scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority)
                .build(), 0);
        return mPermissions.getAllPackagesGranted(pkg);
    }

    public static class Lifecycle extends SystemService {
        private SliceManagerService mService;

+10 −0
Original line number Diff line number Diff line
@@ -133,6 +133,16 @@ public class SlicePermissionManager implements DirtyTracker {
        mHandler.obtainMessage(H.MSG_REMOVE, pkgUser);
    }

    public String[] getAllPackagesGranted(String pkg) {
        ArraySet<String> ret = new ArraySet<>();
        for (SliceAuthority authority : getProvider(new PkgUser(pkg, 0)).getAuthorities()) {
            for (PkgUser pkgUser : authority.getPkgs()) {
                ret.add(pkgUser.mPkg);
            }
        }
        return ret.toArray(new String[ret.size()]);
    }

    public boolean hasFullAccess(String pkg, int userId) {
        PkgUser pkgUser = new PkgUser(pkg, userId);
        return getClient(pkgUser).hasFullAccess();
+110 −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.slice;

import android.app.slice.SliceProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Process;
import android.os.ShellCommand;
import android.util.ArraySet;

import java.io.PrintWriter;
import java.util.List;
import java.util.Set;

public class SliceShellCommand extends ShellCommand {

    private final SliceManagerService mService;

    public SliceShellCommand(SliceManagerService service) {
        mService = service;
    }

    @Override
    public int onCommand(String cmd) {
        if (cmd == null) {
            return handleDefaultCommands(cmd);
        }
        switch (cmd) {
            case "get-permissions":
                return runGetPermissions(getNextArgRequired());
        }
        return 0;
    }

    @Override
    public void onHelp() {
        final PrintWriter pw = getOutPrintWriter();
        pw.println("Status bar commands:");
        pw.println("  help");
        pw.println("    Print this help text.");
        pw.println("");
        pw.println("  get-permissions <authority>");
        pw.println("    List the pkgs that have permission to an authority.");
        pw.println("");

    }

    private int runGetPermissions(String authority) {
        if (Binder.getCallingUid() != Process.SHELL_UID
                && Binder.getCallingUid() != Process.ROOT_UID) {
            getOutPrintWriter().println("Only shell can get permissions");
            return -1;
        }
        Context context = mService.getContext();
        long ident = Binder.clearCallingIdentity();
        try {
            Uri uri = new Uri.Builder()
                    .scheme(ContentResolver.SCHEME_CONTENT)
                    .authority(authority)
                    .build();
            if (!SliceProvider.SLICE_TYPE.equals(context.getContentResolver().getType(uri))) {
                getOutPrintWriter().println(authority + " is not a slice provider");
                return -1;
            }
            Bundle b = context.getContentResolver().call(uri, SliceProvider.METHOD_GET_PERMISSIONS,
                    null, null);
            if (b == null) {
                getOutPrintWriter().println("An error occurred getting permissions");
                return -1;
            }
            String[] permissions = b.getStringArray(SliceProvider.EXTRA_RESULT);
            final PrintWriter pw = getOutPrintWriter();
            Set<String> listedPackages = new ArraySet<>();
            if (permissions != null && permissions.length != 0) {
                List<PackageInfo> apps =
                        context.getPackageManager().getPackagesHoldingPermissions(permissions, 0);
                for (PackageInfo app : apps) {
                    pw.println(app.packageName);
                    listedPackages.add(app.packageName);
                }
            }
            for (String pkg : mService.getAllPackagesGranted(authority)) {
                if (!listedPackages.contains(pkg)) {
                    pw.println(pkg);
                    listedPackages.add(pkg);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        return 0;
    }
}