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

Commit 67507ea3 authored by Jonathan Klee's avatar Jonathan Klee
Browse files

feat: Introduce Hide From Microg feature

parent df7b659b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -6421,6 +6421,10 @@ public final class Settings {
         */
        public static final String PREFERRED_REGION = "preferred_region";
        /** @hide */
        public static final String HIDE_MICROG_PACKAGES_FOR_PACKAGE =
                "hide_microg_packages_for_package";
        /**
         * Setting to enable camera flash notification feature.
         * <ul>
@@ -6607,6 +6611,7 @@ public final class Settings {
            PRIVATE_SETTINGS.add(MOUSE_REVERSE_VERTICAL_SCROLLING);
            PRIVATE_SETTINGS.add(MOUSE_SWAP_PRIMARY_BUTTON);
            PRIVATE_SETTINGS.add(PREFERRED_REGION);
            PRIVATE_SETTINGS.add(HIDE_MICROG_PACKAGES_FOR_PACKAGE);
        }
        /**
+14 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.provider.settings.validators.SettingsValidators.FONT_SCALE
import static android.provider.settings.validators.SettingsValidators.LENIENT_IP_ADDRESS_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_FLOAT_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.URI_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.VIBRATION_INTENSITY_VALIDATOR;
import static android.view.PointerIcon.DEFAULT_POINTER_SCALE;
@@ -268,5 +269,18 @@ public class SystemSettingsValidators {
        VALIDATORS.put(System.NOTIFICATION_COOLDOWN_ALL, BOOLEAN_VALIDATOR);
        VALIDATORS.put(System.NOTIFICATION_COOLDOWN_VIBRATE_UNLOCKED, BOOLEAN_VALIDATOR);
        VALIDATORS.put(System.PREFERRED_REGION, ANY_STRING_VALIDATOR);
        VALIDATORS.put(System.HIDE_MICROG_PACKAGES_FOR_PACKAGE, value -> {
            if (value == null) {
                return true;
            }
            for (String packageName : value.split(",")) {
                final String trimmedPackageName = packageName.trim();
                if (trimmedPackageName.isEmpty()
                        || !PACKAGE_NAME_VALIDATOR.validate(trimmedPackageName)) {
                    return false;
                }
            }
            return true;
        });
    }
}
+83 −0
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 */
public abstract class AppsFilterBase implements AppsFilterSnapshot {
    protected static final String TAG = "AppsFilter";
    private static final String GOOGLE_PLAY_SERVICES_PACKAGE = "com.google.android.gms";
    private static final String GOOGLE_PLAY_STORE_PACKAGE = "com.android.vending";

    // Logs all filtering instead of enforcing
    protected static final boolean DEBUG_ALLOW_ALL = false;
@@ -199,11 +201,78 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
    protected volatile boolean mCacheReady = false;
    protected volatile boolean mCacheEnabled = true;
    protected volatile boolean mNeedToUpdateCacheForImplicitAccess = false;
    @NonNull
    protected volatile SparseArray<ArraySet<String>> mHideMicrogPackagesForCallerByUser =
            new SparseArray<>();

    protected static final boolean CACHE_VALID = true;
    protected static final boolean CACHE_INVALID = false;
    protected final AtomicBoolean mCacheValid = new AtomicBoolean(CACHE_INVALID);

    protected static SparseArray<ArraySet<String>> copyPackageNamesByUser(
            @NonNull SparseArray<ArraySet<String>> packageNamesByUser) {
        final SparseArray<ArraySet<String>> copy = new SparseArray<>(packageNamesByUser.size());
        for (int i = 0; i < packageNamesByUser.size(); i++) {
            final ArraySet<String> packageNames = packageNamesByUser.valueAt(i);
            copy.put(packageNamesByUser.keyAt(i),
                    packageNames == null ? null : new ArraySet<>(packageNames));
        }
        return copy;
    }

    private static boolean isMicrogPackageHiddenByConfig(@NonNull String packageName) {
        return GOOGLE_PLAY_SERVICES_PACKAGE.equals(packageName)
                || GOOGLE_PLAY_STORE_PACKAGE.equals(packageName);
    }

    private boolean shouldHideMicrogPackagesForCaller(int callingUserId,
            @Nullable String[] callingPackageNames, @NonNull String targetPackageName) {
        if (!isMicrogPackageHiddenByConfig(targetPackageName)) {
            return false;
        }

        final ArraySet<String> configuredPackageNames =
                mHideMicrogPackagesForCallerByUser.get(callingUserId);
        if (configuredPackageNames == null || configuredPackageNames.isEmpty()
                || callingPackageNames == null) {
            return false;
        }

        for (String callingPackageName : callingPackageNames) {
            if (configuredPackageNames.contains(callingPackageName)) {
                return true;
            }
        }
        return false;
    }

    private boolean shouldHideMicrogPackagesForCaller(int callingUid,
            @Nullable PackageStateInternal callingPkgSetting,
            @NonNull ArraySet<PackageStateInternal> callingSharedPkgSettings,
            @NonNull PackageStateInternal targetPkgSetting) {
        if (!isMicrogPackageHiddenByConfig(targetPkgSetting.getPackageName())) {
            return false;
        }

        final ArraySet<String> configuredPackageNames =
                mHideMicrogPackagesForCallerByUser.get(UserHandle.getUserId(callingUid));
        if (configuredPackageNames == null || configuredPackageNames.isEmpty()) {
            return false;
        }

        if (callingPkgSetting != null) {
            return configuredPackageNames.contains(callingPkgSetting.getPackageName());
        }

        for (int i = 0; i < callingSharedPkgSettings.size(); i++) {
            if (configuredPackageNames.contains(
                    callingSharedPkgSettings.valueAt(i).getPackageName())) {
                return true;
            }
        }
        return false;
    }

    protected boolean isForceQueryable(int callingAppId) {
        return mForceQueryable.contains(callingAppId);
    }
@@ -342,6 +411,12 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
                    || callingAppId == targetPkgSetting.getAppId()) {
                return false;
            } else if (Process.isSdkSandboxUid(callingAppId)) {
                final Computer computer = (Computer) snapshot;
                if (shouldHideMicrogPackagesForCaller(UserHandle.getUserId(callingUid),
                        computer.getPackagesForUid(Process.getAppUidForSdkSandboxUid(callingUid)),
                        targetPkgSetting.getPackageName())) {
                    return true;
                }
                final int targetAppId = targetPkgSetting.getAppId();
                final int targetUid = UserHandle.getUid(userId, targetAppId);
                // we only allow sdk sandbox processes access to forcequeryable packages or
@@ -453,6 +528,14 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            }

            if (shouldHideMicrogPackagesForCaller(callingUid, callingPkgSetting,
                    callingSharedPkgSettings, targetPkgSetting)) {
                if (DEBUG_LOGGING) {
                    log(callingSetting, targetPkgSetting, "hidden package by microg config");
                }
                return true;
            }

            if (callingPkgSetting != null) {
                if (callingPkgSetting.getPkg() != null
                        && !mFeatureConfig.packageIsEnabled(callingPkgSetting.getPkg())) {
+43 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import android.provider.DeviceConfig;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseSetArray;

@@ -496,6 +497,31 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
                PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__BOOT);
    }

    public void updateHiddenMicrogPackagesConfig(Computer snapshot,
            @NonNull SparseArray<ArraySet<String>> packageNamesByUser) {
        final SparseArray<ArraySet<String>> oldPackageNamesByUser =
                mHideMicrogPackagesForCallerByUser;
        final SparseArray<ArraySet<String>> newPackageNamesByUser =
                copyPackageNamesByUser(packageNamesByUser);
        if (samePackageNamesByUser(oldPackageNamesByUser, newPackageNamesByUser)) {
            return;
        }

        mHideMicrogPackagesForCallerByUser = newPackageNamesByUser;

        if (mCacheReady) {
            for (UserInfo userInfo : snapshot.getUserInfos()) {
                final int userId = userInfo.id;
                if (!Objects.equals(oldPackageNamesByUser.get(userId),
                        newPackageNamesByUser.get(userId))) {
                    updateEntireShouldFilterCache(snapshot, userId);
                }
            }
        }

        onChanged();
    }

    /**
     * Adds a package that should be considered when filtering visibility between apps.
     *
@@ -1295,4 +1321,21 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
        FrameworkStatsLog.write(PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED,
                eventId, appId, latency, userCount, packageCount, mShouldFilterCache.size());
    }

    private static boolean samePackageNamesByUser(
            @NonNull SparseArray<ArraySet<String>> oldPackageNamesByUser,
            @NonNull SparseArray<ArraySet<String>> newPackageNamesByUser) {
        if (oldPackageNamesByUser.size() != newPackageNamesByUser.size()) {
            return false;
        }

        for (int i = 0; i < oldPackageNamesByUser.size(); i++) {
            final int userId = oldPackageNamesByUser.keyAt(i);
            if (!Objects.equals(oldPackageNamesByUser.valueAt(i),
                    newPackageNamesByUser.get(userId))) {
                return false;
            }
        }
        return true;
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ public final class AppsFilterSnapshotImpl extends AppsFilterBase {
        }
        mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>();
        mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute;
        mHideMicrogPackagesForCallerByUser =
                copyPackageNamesByUser(orig.mHideMicrogPackagesForCallerByUser);
        mForceQueryableByDevicePackageNames =
                Arrays.copyOf(orig.mForceQueryableByDevicePackageNames,
                        orig.mForceQueryableByDevicePackageNames.length);
Loading