Loading core/java/android/app/slice/SliceProvider.java +15 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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; Loading Loading @@ -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); } Loading services/core/java/com/android/server/slice/SliceManagerService.java +18 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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; Loading services/core/java/com/android/server/slice/SlicePermissionManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading services/core/java/com/android/server/slice/SliceShellCommand.java 0 → 100644 +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; } } Loading
core/java/android/app/slice/SliceProvider.java +15 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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; Loading Loading @@ -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); } Loading
services/core/java/com/android/server/slice/SliceManagerService.java +18 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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; Loading
services/core/java/com/android/server/slice/SlicePermissionManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading
services/core/java/com/android/server/slice/SliceShellCommand.java 0 → 100644 +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; } }