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

Commit 822a3610 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Flag dump: remove inconsistent dump" into main

parents afeced01 44cd76b4
Loading
Loading
Loading
Loading
+24 −105
Original line number Diff line number Diff line
@@ -76,7 +76,6 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.sysprop.BluetoothProperties;
@@ -118,7 +117,6 @@ import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;

class BluetoothManagerService {
    private static final String TAG = BluetoothManagerService.class.getSimpleName();
@@ -2317,13 +2315,6 @@ class BluetoothManagerService {
        }
        String errorMsg = null;

        String flagString = "";
        try {
            flagString = dumpBluetoothFlags(writer);
        } catch (Exception e) {
            writer.println("Exception while dumping Bluetooth Flags");
        }

        writer.println("Bluetooth Status");
        writer.println("  enabled: " + isEnabled());
        writer.println("  state: " + mState);
@@ -2373,17 +2364,19 @@ class BluetoothManagerService {

        writer.println("");
        writer.flush();

        dumpBluetoothFlags(writer);
        writer.println("");

        if (mAdapter == null) {
            errorMsg = "Bluetooth Service not connected";
        } else {
            if (args.length == 0) {
                // Add arg to produce output
                args = new String[1];
                args[0] = "--print";
            }

        writer.println(flagString);

        if (mAdapter == null) {
            errorMsg = "Bluetooth Service not connected";
        } else {
            try {
                mAdapter.getAdapterBinder().asBinder().dumpAsync(fd, args);
            } catch (RemoteException re) {
@@ -2395,96 +2388,22 @@ class BluetoothManagerService {
        }
    }

    private static class FlagValue {
        private final String mSnakeName;
        private final boolean mDefaultValue;
        private final boolean mManuallyEnabledInJava;
        private final boolean mManuallyEnabledInNative;

        FlagValue(String name, boolean defaultValue) {
            mSnakeName = name.replaceAll("([A-Z])", "_$1").toLowerCase(Locale.US);
            mDefaultValue = defaultValue;
            mManuallyEnabledInJava = getJavaFlagValue();
            mManuallyEnabledInNative = getNativeFlagValue();
        }

        private boolean getJavaFlagValue() {
            return DeviceConfig.getBoolean(
                    DeviceConfig.NAMESPACE_BLUETOOTH,
                    "com.android.bluetooth.flags." + mSnakeName,
                    false);
        }

        private boolean getNativeFlagValue() {
            return SystemProperties.getBoolean(
                    "persist.device_config.aconfig_flags.bluetooth.com.android.bluetooth.flags."
                            + mSnakeName,
                    false);
        }

        boolean isManuallyOverridden() {
            return mManuallyEnabledInJava || mManuallyEnabledInNative;
        }

        boolean isPartiallyOverridden() {
            return isManuallyOverridden()
                    && (mDefaultValue != mManuallyEnabledInJava
                            || mDefaultValue != mManuallyEnabledInNative
                            || mManuallyEnabledInJava != mManuallyEnabledInNative);
        }

        static String toIcon(boolean flagValue) {
            return flagValue ? "[■]" : "[ ]";
        }

        void dump(StringBuilder sb) {
            sb.append("\t").append(toIcon(mDefaultValue)).append(": ").append(mSnakeName);
            if (isManuallyOverridden()) {
                sb.append(" (Manual override)");
                if (isPartiallyOverridden()) {
                    sb.append(String.format(" (%s: Java)", toIcon(mManuallyEnabledInJava)));
                    sb.append(String.format(" (%s: Native)", toIcon(mManuallyEnabledInNative)));
                    sb.append(" INCONSISTENT OVERRIDE FOR THIS FLAG.")
                            .append(" This can lead to unpredictable behavior.");
                }
            }
            sb.append("\n");
        }
    }

    private String dumpBluetoothFlags(PrintWriter writer) {
        List<FlagValue> flags =
    private void dumpBluetoothFlags(PrintWriter writer) {
        writer.println("🚩Flag dump:");
        Arrays.stream(Flags.class.getDeclaredMethods())
                        .map(
                .forEach(
                        (Method m) -> {
                            String name =
                                    m.getName().replaceAll("([A-Z])", "_$1").toLowerCase(Locale.US);
                            boolean flagValue;
                            try {
                                        return new FlagValue(m.getName(), (boolean) m.invoke(null));
                                flagValue = (boolean) m.invoke(null);
                            } catch (IllegalAccessException | InvocationTargetException e) {
                                        writer.println("Exception caught while dumping flag:" + e);
                                writer.println("Cannot invoke " + name + " flag:" + e);
                                throw new RuntimeException(e);
                            }
                                })
                        .collect(Collectors.toList());

        StringBuilder flagOverride = new StringBuilder();
        flags.stream().filter(FlagValue::isManuallyOverridden).forEach(f -> f.dump(flagOverride));
        if (flagOverride.length() > 0) {
            writer.println("🚩Some flags have a local override. Make sure this is expected");
            if (flags.stream().anyMatch(FlagValue::isPartiallyOverridden)) {
                writer.println("CRITICAL WARNING:");
                writer.println("\tSome flags differ between native and java code !");
                writer.println(
                        "\tEither they are only enabled in java or only enabled in native. This can"
                                + " lead to critical failure and/or hard to debug issues.");
            }

            writer.println(flagOverride.toString());
            writer.println("---------------------------------------------------------------------");
            writer.println("");
        }
        StringBuilder flagDumpBuilder = new StringBuilder("🚩Flag dump:\n");
        flags.stream().forEach(f -> f.dump(flagDumpBuilder));
        return flagDumpBuilder.toString();
                            writer.println("\t" + (flagValue ? "[■]" : "[ ]") + ": " + name);
                        });
    }

    private void dumpProto(FileDescriptor fd) {