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

This commit is contained in:
TreeHugger Robot
2018-05-16 00:12:32 +00:00
committed by Android (Google) Code Review
4 changed files with 153 additions and 0 deletions

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -0,0 +1,110 @@
/*
* 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;
}
}