Merge "AppOps: fix nested op tracking, new API to get apps using permissions."
This commit is contained in:
committed by
Android (Google) Code Review
commit
2125dd57cc
@@ -6592,6 +6592,7 @@ package android.content.pm {
|
|||||||
method public abstract int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
|
method public abstract int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||||
method public abstract android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
method public abstract android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||||
method public abstract java.lang.String[] getPackagesForUid(int);
|
method public abstract java.lang.String[] getPackagesForUid(int);
|
||||||
|
method public abstract java.util.List<android.content.pm.PackageInfo> getPackagesHoldingPermissions(java.lang.String[], int);
|
||||||
method public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
method public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||||
method public abstract android.content.pm.PermissionInfo getPermissionInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
method public abstract android.content.pm.PermissionInfo getPermissionInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||||
method public abstract int getPreferredActivities(java.util.List<android.content.IntentFilter>, java.util.List<android.content.ComponentName>, java.lang.String);
|
method public abstract int getPreferredActivities(java.util.List<android.content.IntentFilter>, java.util.List<android.content.ComponentName>, java.lang.String);
|
||||||
@@ -21689,6 +21690,7 @@ package android.test.mock {
|
|||||||
method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
|
method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||||
method public android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
method public android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||||
method public java.lang.String[] getPackagesForUid(int);
|
method public java.lang.String[] getPackagesForUid(int);
|
||||||
|
method public java.util.List<android.content.pm.PackageInfo> getPackagesHoldingPermissions(java.lang.String[], int);
|
||||||
method public android.content.pm.PermissionGroupInfo getPermissionGroupInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
method public android.content.pm.PermissionGroupInfo getPermissionGroupInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||||
method public android.content.pm.PermissionInfo getPermissionInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
method public android.content.pm.PermissionInfo getPermissionInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||||
method public int getPreferredActivities(java.util.List<android.content.IntentFilter>, java.util.List<android.content.ComponentName>, java.lang.String);
|
method public int getPreferredActivities(java.util.List<android.content.IntentFilter>, java.util.List<android.content.ComponentName>, java.lang.String);
|
||||||
|
|||||||
@@ -442,6 +442,28 @@ final class ApplicationPackageManager extends PackageManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public List<PackageInfo> getPackagesHoldingPermissions(
|
||||||
|
String[] permissions, int flags) {
|
||||||
|
final int userId = mContext.getUserId();
|
||||||
|
try {
|
||||||
|
final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
|
||||||
|
PackageInfo lastItem = null;
|
||||||
|
ParceledListSlice<PackageInfo> slice;
|
||||||
|
|
||||||
|
do {
|
||||||
|
final String lastKey = lastItem != null ? lastItem.packageName : null;
|
||||||
|
slice = mPM.getPackagesHoldingPermissions(permissions, flags, lastKey, userId);
|
||||||
|
lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
|
||||||
|
} while (!slice.isLastSlice());
|
||||||
|
|
||||||
|
return packageInfos;
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw new RuntimeException("Package manager has died", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public List<ApplicationInfo> getInstalledApplications(int flags) {
|
public List<ApplicationInfo> getInstalledApplications(int flags) {
|
||||||
|
|||||||
@@ -129,6 +129,15 @@ interface IPackageManager {
|
|||||||
*/
|
*/
|
||||||
ParceledListSlice getInstalledPackages(int flags, in String lastRead, in int userId);
|
ParceledListSlice getInstalledPackages(int flags, in String lastRead, in int userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implements getPackagesHoldingPermissions via a "last returned row"
|
||||||
|
* mechanism that is not exposed in the API. This is to get around the IPC
|
||||||
|
* limit that kicks in when flags are included that bloat up the data
|
||||||
|
* returned.
|
||||||
|
*/
|
||||||
|
ParceledListSlice getPackagesHoldingPermissions(in String[] permissions,
|
||||||
|
int flags, in String lastRead, int userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implements getInstalledApplications via a "last returned row"
|
* This implements getInstalledApplications via a "last returned row"
|
||||||
* mechanism that is not exposed in the API. This is to get around the IPC
|
* mechanism that is not exposed in the API. This is to get around the IPC
|
||||||
|
|||||||
@@ -1512,10 +1512,42 @@ public abstract class PackageManager {
|
|||||||
* @see #GET_SERVICES
|
* @see #GET_SERVICES
|
||||||
* @see #GET_SIGNATURES
|
* @see #GET_SIGNATURES
|
||||||
* @see #GET_UNINSTALLED_PACKAGES
|
* @see #GET_UNINSTALLED_PACKAGES
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public abstract List<PackageInfo> getInstalledPackages(int flags);
|
public abstract List<PackageInfo> getInstalledPackages(int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a List of all installed packages that are currently
|
||||||
|
* holding any of the given permissions.
|
||||||
|
*
|
||||||
|
* @param flags Additional option flags. Use any combination of
|
||||||
|
* {@link #GET_ACTIVITIES},
|
||||||
|
* {@link #GET_GIDS},
|
||||||
|
* {@link #GET_CONFIGURATIONS},
|
||||||
|
* {@link #GET_INSTRUMENTATION},
|
||||||
|
* {@link #GET_PERMISSIONS},
|
||||||
|
* {@link #GET_PROVIDERS},
|
||||||
|
* {@link #GET_RECEIVERS},
|
||||||
|
* {@link #GET_SERVICES},
|
||||||
|
* {@link #GET_SIGNATURES},
|
||||||
|
* {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
|
||||||
|
*
|
||||||
|
* @return Returns a List of PackageInfo objects, one for each installed
|
||||||
|
* application that is holding any of the permissions that were provided.
|
||||||
|
*
|
||||||
|
* @see #GET_ACTIVITIES
|
||||||
|
* @see #GET_GIDS
|
||||||
|
* @see #GET_CONFIGURATIONS
|
||||||
|
* @see #GET_INSTRUMENTATION
|
||||||
|
* @see #GET_PERMISSIONS
|
||||||
|
* @see #GET_PROVIDERS
|
||||||
|
* @see #GET_RECEIVERS
|
||||||
|
* @see #GET_SERVICES
|
||||||
|
* @see #GET_SIGNATURES
|
||||||
|
* @see #GET_UNINSTALLED_PACKAGES
|
||||||
|
*/
|
||||||
|
public abstract List<PackageInfo> getPackagesHoldingPermissions(
|
||||||
|
String[] permissions, int flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a List of all packages that are installed on the device, for a specific user.
|
* Return a List of all packages that are installed on the device, for a specific user.
|
||||||
* Requesting a list of installed packages for another user
|
* Requesting a list of installed packages for another user
|
||||||
@@ -1742,14 +1774,14 @@ public abstract class PackageManager {
|
|||||||
/**
|
/**
|
||||||
* Return a List of all application packages that are installed on the
|
* Return a List of all application packages that are installed on the
|
||||||
* device. If flag GET_UNINSTALLED_PACKAGES has been set, a list of all
|
* device. If flag GET_UNINSTALLED_PACKAGES has been set, a list of all
|
||||||
* applications including those deleted with DONT_DELETE_DATA(partially
|
* applications including those deleted with DONT_DELETE_DATA (partially
|
||||||
* installed apps with data directory) will be returned.
|
* installed apps with data directory) will be returned.
|
||||||
*
|
*
|
||||||
* @param flags Additional option flags. Use any combination of
|
* @param flags Additional option flags. Use any combination of
|
||||||
* {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
|
* {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
|
||||||
* {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
|
* {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
|
||||||
*
|
*
|
||||||
* @return A List of ApplicationInfo objects, one for each application that
|
* @return Returns a List of ApplicationInfo objects, one for each application that
|
||||||
* is installed on the device. In the unlikely case of there being
|
* is installed on the device. In the unlikely case of there being
|
||||||
* no installed applications, an empty list is returned.
|
* no installed applications, an empty list is returned.
|
||||||
* If flag GET_UNINSTALLED_PACKAGES is set, a list of all
|
* If flag GET_UNINSTALLED_PACKAGES is set, a list of all
|
||||||
|
|||||||
@@ -233,6 +233,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
+ " code " + code + " time=" + op.time + " duration=" + op.duration
|
+ " code " + code + " time=" + op.time + " duration=" + op.duration
|
||||||
+ " nesting=" + op.nesting);
|
+ " nesting=" + op.nesting);
|
||||||
}
|
}
|
||||||
|
op.nesting = 0;
|
||||||
} else {
|
} else {
|
||||||
op.nesting--;
|
op.nesting--;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2943,6 +2943,74 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
|
||||||
|
String[] permissions, int flags, String lastRead, int userId) {
|
||||||
|
if (!sUserManager.exists(userId)) return null;
|
||||||
|
final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>();
|
||||||
|
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
|
||||||
|
|
||||||
|
// writer
|
||||||
|
synchronized (mPackages) {
|
||||||
|
ArrayList<String> keysList = new ArrayList<String>();
|
||||||
|
if (listUninstalled) {
|
||||||
|
for (PackageSetting ps : mSettings.mPackages.values()) {
|
||||||
|
for (String perm : permissions) {
|
||||||
|
if (ps.grantedPermissions.contains(perm)) {
|
||||||
|
keysList.add(ps.name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (PackageParser.Package pkg : mPackages.values()) {
|
||||||
|
PackageSetting ps = (PackageSetting)pkg.mExtras;
|
||||||
|
if (ps != null) {
|
||||||
|
for (String perm : permissions) {
|
||||||
|
if (ps.grantedPermissions.contains(perm)) {
|
||||||
|
keysList.add(ps.name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] keys = new String[keysList.size()];
|
||||||
|
keysList.toArray(keys);
|
||||||
|
Arrays.sort(keys);
|
||||||
|
int i = getContinuationPoint(keys, lastRead);
|
||||||
|
final int N = keys.length;
|
||||||
|
|
||||||
|
while (i < N) {
|
||||||
|
final String packageName = keys[i++];
|
||||||
|
|
||||||
|
PackageInfo pi = null;
|
||||||
|
if (listUninstalled) {
|
||||||
|
final PackageSetting ps = mSettings.mPackages.get(packageName);
|
||||||
|
if (ps != null) {
|
||||||
|
pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final PackageParser.Package p = mPackages.get(packageName);
|
||||||
|
if (p != null) {
|
||||||
|
pi = generatePackageInfo(p, flags, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pi != null && list.append(pi)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == N) {
|
||||||
|
list.setLastSlice(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
|
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
|
||||||
String lastRead, int userId) {
|
String lastRead, int userId) {
|
||||||
|
|||||||
@@ -146,6 +146,12 @@ public class MockPackageManager extends PackageManager {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions,
|
||||||
|
int flags) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@Override
|
@Override
|
||||||
public List<PackageInfo> getInstalledPackages(int flags, int userId) {
|
public List<PackageInfo> getInstalledPackages(int flags, int userId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user