Loading src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +45 −64 Original line number Diff line number Diff line Loading @@ -57,9 +57,8 @@ import static java.lang.System.currentTimeMillis; import static java.util.concurrent.TimeUnit.DAYS; import android.app.AppOpsManager; import android.app.AppOpsManager.HistoricalOps; import android.app.AppOpsManager.HistoricalOpsRequest; import android.app.AppOpsManager.HistoricalPackageOps; import android.app.AppOpsManager.OpEntry; import android.app.AppOpsManager.PackageOps; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; Loading Loading @@ -97,7 +96,6 @@ import androidx.core.util.Preconditions; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.ui.AppPermissionActivity; import com.android.packageinstaller.permission.utils.CollectionUtils; import com.android.permissioncontroller.R; import java.io.BufferedReader; Loading @@ -106,13 +104,10 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.BooleanSupplier; /** Loading @@ -133,8 +128,6 @@ public class LocationAccessCheck { private static final String LOG_TAG = LocationAccessCheck.class.getSimpleName(); private static final boolean DEBUG = false; private static final long GET_HISTORIAL_OPS_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(3); /** Lock required for all methods called {@code ...Locked} */ private static final Object sLock = new Object(); Loading Loading @@ -357,15 +350,8 @@ public class LocationAccessCheck { return; } HistoricalOpsRequest request = new HistoricalOpsRequest.Builder( Instant.EPOCH.toEpochMilli(), Long.MAX_VALUE) .setOpNames(CollectionUtils.singletonOrEmpty(OPSTR_FINE_LOCATION)) .build(); CompletableFuture<HistoricalOps> ops = new CompletableFuture<>(); mAppOpsManager.getHistoricalOps(request, mContext.getMainExecutor(), ops::complete); addLocationNotificationIfNeeded( ops.get(GET_HISTORIAL_OPS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); addLocationNotificationIfNeeded(mAppOpsManager.getPackagesForOps( new String[]{OPSTR_FINE_LOCATION})); service.jobFinished(params, false); } catch (Exception e) { Log.e(LOG_TAG, "Could not check for location access", e); Loading @@ -378,7 +364,7 @@ public class LocationAccessCheck { } } private void addLocationNotificationIfNeeded(@NonNull HistoricalOps ops) private void addLocationNotificationIfNeeded(@NonNull List<PackageOps> ops) throws InterruptedException { synchronized (sLock) { List<UserPackage> packages = getLocationUsersWithNoNotificationYetLocked(ops); Loading Loading @@ -435,26 +421,22 @@ public class LocationAccessCheck { * @throws InterruptedException If {@link #mShouldCancel} */ private @NonNull List<UserPackage> getLocationUsersWithNoNotificationYetLocked( @NonNull HistoricalOps allOps) throws InterruptedException { @NonNull List<PackageOps> allOps) throws InterruptedException { List<UserPackage> pkgsWithLocationAccess = new ArrayList<>(); List<UserHandle> profiles = mUserManager.getUserProfiles(); LocationManager lm = mContext.getSystemService(LocationManager.class); int numUid = allOps.getUidCount(); for (int uidNum = 0; uidNum < numUid; uidNum++) { AppOpsManager.HistoricalUidOps uidOps = allOps.getUidOpsAt(uidNum); int numPkgs = uidOps.getPackageCount(); int numPkgs = allOps.size(); for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { HistoricalPackageOps ops = uidOps.getPackageOpsAt(pkgNum); PackageOps packageOps = allOps.get(pkgNum); String pkg = ops.getPackageName(); String pkg = packageOps.getPackageName(); if (pkg.equals(OS_PKG) || lm.isProviderPackage(pkg)) { continue; } UserHandle user = getUserHandleForUid(uidOps.getUid()); UserHandle user = getUserHandleForUid(packageOps.getUid()); // Do not handle apps that belong to a different profile user group if (!profiles.contains(user)) { continue; Loading Loading @@ -487,18 +469,17 @@ public class LocationAccessCheck { continue; } int numOps = ops.getOpCount(); int numOps = packageOps.getOps().size(); for (int opNum = 0; opNum < numOps; opNum++) { AppOpsManager.HistoricalOp op = ops.getOpAt(opNum); OpEntry entry = packageOps.getOps().get(opNum); if (op.getBackgroundAccessCount(AppOpsManager.OP_FLAGS_ALL_TRUSTED) > 0) { if (entry.getLastAccessBackgroundTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED) > 0) { pkgsWithLocationAccess.add(userPkg); break; } } } } ArraySet<UserPackage> alreadyNotifiedPkgs = loadAlreadyNotifiedPackagesLocked(); throwInterruptedExceptionIfTaskIsCanceled(); Loading Loading
src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +45 −64 Original line number Diff line number Diff line Loading @@ -57,9 +57,8 @@ import static java.lang.System.currentTimeMillis; import static java.util.concurrent.TimeUnit.DAYS; import android.app.AppOpsManager; import android.app.AppOpsManager.HistoricalOps; import android.app.AppOpsManager.HistoricalOpsRequest; import android.app.AppOpsManager.HistoricalPackageOps; import android.app.AppOpsManager.OpEntry; import android.app.AppOpsManager.PackageOps; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; Loading Loading @@ -97,7 +96,6 @@ import androidx.core.util.Preconditions; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.ui.AppPermissionActivity; import com.android.packageinstaller.permission.utils.CollectionUtils; import com.android.permissioncontroller.R; import java.io.BufferedReader; Loading @@ -106,13 +104,10 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.BooleanSupplier; /** Loading @@ -133,8 +128,6 @@ public class LocationAccessCheck { private static final String LOG_TAG = LocationAccessCheck.class.getSimpleName(); private static final boolean DEBUG = false; private static final long GET_HISTORIAL_OPS_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(3); /** Lock required for all methods called {@code ...Locked} */ private static final Object sLock = new Object(); Loading Loading @@ -357,15 +350,8 @@ public class LocationAccessCheck { return; } HistoricalOpsRequest request = new HistoricalOpsRequest.Builder( Instant.EPOCH.toEpochMilli(), Long.MAX_VALUE) .setOpNames(CollectionUtils.singletonOrEmpty(OPSTR_FINE_LOCATION)) .build(); CompletableFuture<HistoricalOps> ops = new CompletableFuture<>(); mAppOpsManager.getHistoricalOps(request, mContext.getMainExecutor(), ops::complete); addLocationNotificationIfNeeded( ops.get(GET_HISTORIAL_OPS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); addLocationNotificationIfNeeded(mAppOpsManager.getPackagesForOps( new String[]{OPSTR_FINE_LOCATION})); service.jobFinished(params, false); } catch (Exception e) { Log.e(LOG_TAG, "Could not check for location access", e); Loading @@ -378,7 +364,7 @@ public class LocationAccessCheck { } } private void addLocationNotificationIfNeeded(@NonNull HistoricalOps ops) private void addLocationNotificationIfNeeded(@NonNull List<PackageOps> ops) throws InterruptedException { synchronized (sLock) { List<UserPackage> packages = getLocationUsersWithNoNotificationYetLocked(ops); Loading Loading @@ -435,26 +421,22 @@ public class LocationAccessCheck { * @throws InterruptedException If {@link #mShouldCancel} */ private @NonNull List<UserPackage> getLocationUsersWithNoNotificationYetLocked( @NonNull HistoricalOps allOps) throws InterruptedException { @NonNull List<PackageOps> allOps) throws InterruptedException { List<UserPackage> pkgsWithLocationAccess = new ArrayList<>(); List<UserHandle> profiles = mUserManager.getUserProfiles(); LocationManager lm = mContext.getSystemService(LocationManager.class); int numUid = allOps.getUidCount(); for (int uidNum = 0; uidNum < numUid; uidNum++) { AppOpsManager.HistoricalUidOps uidOps = allOps.getUidOpsAt(uidNum); int numPkgs = uidOps.getPackageCount(); int numPkgs = allOps.size(); for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { HistoricalPackageOps ops = uidOps.getPackageOpsAt(pkgNum); PackageOps packageOps = allOps.get(pkgNum); String pkg = ops.getPackageName(); String pkg = packageOps.getPackageName(); if (pkg.equals(OS_PKG) || lm.isProviderPackage(pkg)) { continue; } UserHandle user = getUserHandleForUid(uidOps.getUid()); UserHandle user = getUserHandleForUid(packageOps.getUid()); // Do not handle apps that belong to a different profile user group if (!profiles.contains(user)) { continue; Loading Loading @@ -487,18 +469,17 @@ public class LocationAccessCheck { continue; } int numOps = ops.getOpCount(); int numOps = packageOps.getOps().size(); for (int opNum = 0; opNum < numOps; opNum++) { AppOpsManager.HistoricalOp op = ops.getOpAt(opNum); OpEntry entry = packageOps.getOps().get(opNum); if (op.getBackgroundAccessCount(AppOpsManager.OP_FLAGS_ALL_TRUSTED) > 0) { if (entry.getLastAccessBackgroundTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED) > 0) { pkgsWithLocationAccess.add(userPkg); break; } } } } ArraySet<UserPackage> alreadyNotifiedPkgs = loadAlreadyNotifiedPackagesLocked(); throwInterruptedExceptionIfTaskIsCanceled(); Loading