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

Commit 7955bd97 authored by Sunny Goyal's avatar Sunny Goyal Committed by Android (Google) Code Review
Browse files

Merge "Simplifying settings activity" into main

parents c8ac1b41 6eb256d7
Loading
Loading
Loading
Loading
+49 −133
Original line number Diff line number Diff line
@@ -15,9 +15,6 @@
 */
package com.android.launcher3.uioverrides.flags;

import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_PACKAGE_CHANGED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.view.View.GONE;
@@ -30,7 +27,7 @@ import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_H
import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT;
import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_HIGHLIGHT_KEY;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
@@ -40,7 +37,6 @@ import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_C
import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN;
import static com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP;

import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -48,23 +44,17 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.ArrayMap;
import android.util.Pair;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceDataStore;
@@ -81,7 +71,6 @@ import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.SimpleBroadcastReceiver;

import java.util.ArrayList;
import java.util.List;
@@ -92,30 +81,32 @@ import java.util.stream.Collectors;
 * Dev-build only UI allowing developers to toggle flag settings and plugins.
 * See {@link FeatureFlags}.
 */
@TargetApi(Build.VERSION_CODES.O)
public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
public class DeveloperOptionsUI {

    private static final String ACTION_PLUGIN_SETTINGS = "com.android.systemui.action.PLUGIN_SETTINGS";
    private static final String ACTION_PLUGIN_SETTINGS =
            "com.android.systemui.action.PLUGIN_SETTINGS";
    private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";

    private final SimpleBroadcastReceiver mPluginReceiver =
            new SimpleBroadcastReceiver(i -> loadPluginPrefs());

    private PreferenceScreen mPreferenceScreen;
    private final PreferenceFragmentCompat mFragment;
    private final PreferenceScreen mPreferenceScreen;

    private PreferenceCategory mPluginsCategory;
    private FlagTogglerPrefUi mFlagTogglerPrefUi;

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        mPluginReceiver.registerPkgActions(getContext(), null,
                ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REMOVED);
        mPluginReceiver.register(getContext(), Intent.ACTION_USER_UNLOCKED);
    public DeveloperOptionsUI(PreferenceFragmentCompat fragment, PreferenceCategory flags) {
        mFragment = fragment;
        mPreferenceScreen = fragment.getPreferenceScreen();

        mPreferenceScreen = getPreferenceManager().createPreferenceScreen(getContext());
        setPreferenceScreen(mPreferenceScreen);
        // Add search bar
        View listView = mFragment.getListView();
        ViewGroup parent = (ViewGroup) listView.getParent();
        View topBar = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.developer_options_top_bar, parent, false);
        parent.addView(topBar, parent.indexOfChild(listView));
        initSearch(topBar.findViewById(R.id.filter_box));

        new FlagTogglerPrefUi(mFragment.requireActivity(), topBar.findViewById(R.id.flag_apply_btn))
                .applyTo(flags);

        initFlags();
        loadPluginPrefs();
        maybeAddSandboxCategory();
        addOnboardingPrefsCatergory();
@@ -123,10 +114,6 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
            addAllAppsFromOverviewCatergory();
        }
        addCustomLpnhCategory();

        if (getActivity() != null) {
            getActivity().setTitle("Developer Options");
        }
    }

    private void filterPreferences(String query, PreferenceGroup pg) {
@@ -149,21 +136,13 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
        pg.setVisible(hidden != count);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        EditText filterBox = view.findViewById(R.id.filter_box);
        filterBox.setVisibility(VISIBLE);
    private void initSearch(EditText filterBox) {
        filterBox.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

            @Override
            public void afterTextChanged(Editable editable) {
@@ -172,85 +151,33 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
            }
        });

        if (getArguments() != null) {
            String filter = getArguments().getString(EXTRA_FRAGMENT_ARG_KEY);
        if (mFragment.getArguments() != null) {
            String filter = mFragment.getArguments().getString(EXTRA_FRAGMENT_HIGHLIGHT_KEY);
            // Normally EXTRA_FRAGMENT_ARG_KEY is used to highlight the preference with the given
            // key. This is a slight variation where we instead filter by the human-readable titles.
            if (filter != null) {
                filterBox.setText(filter);
            }
        }

        View listView = getListView();
        final int bottomPadding = listView.getPaddingBottom();
        listView.setOnApplyWindowInsetsListener((v, insets) -> {
            v.setPadding(
                    v.getPaddingLeft(),
                    v.getPaddingTop(),
                    v.getPaddingRight(),
                    bottomPadding + insets.getSystemWindowInsetBottom());
            return insets.consumeSystemWindowInsets();
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mPluginReceiver.unregisterReceiverSafely(getContext());
    }

    private PreferenceCategory newCategory(String title) {
        return newCategory(title, null);
    }

    private PreferenceCategory newCategory(String title, @Nullable String summary) {
        PreferenceCategory category = new PreferenceCategory(getContext());
        category.setOrder(Preference.DEFAULT_ORDER);
        category.setTitle(title);
        if (!TextUtils.isEmpty(summary)) {
            category.setSummary(summary);
        }
        mPreferenceScreen.addPreference(category);
        return category;
    }

    private void initFlags() {
        if (!FeatureFlags.showFlagTogglerUi(getContext())) {
            return;
        }

        mFlagTogglerPrefUi = new FlagTogglerPrefUi(this);
        mFlagTogglerPrefUi.applyTo(newCategory("Feature flags", "Long press to reset"));
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (mFlagTogglerPrefUi != null) {
            mFlagTogglerPrefUi.onCreateOptionsMenu(menu);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mFlagTogglerPrefUi != null) {
            mFlagTogglerPrefUi.onOptionsItemSelected(item);
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onStop() {
        if (mFlagTogglerPrefUi != null) {
            mFlagTogglerPrefUi.onStop();
        }
        super.onStop();
    private Context getContext() {
        return mFragment.requireContext();
    }

    private void loadPluginPrefs() {
        if (mPluginsCategory != null) {
            mPreferenceScreen.removePreference(mPluginsCategory);
        }
        if (!PluginManagerWrapper.hasPlugins(getActivity())) {
        if (!PluginManagerWrapper.hasPlugins(getContext())) {
            mPluginsCategory = null;
            return;
        }
@@ -323,68 +250,57 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
        launchTutorialStepMenuPreference.setKey("launchTutorialStepMenu");
        launchTutorialStepMenuPreference.setTitle("Launch Gesture Tutorial Steps menu");
        launchTutorialStepMenuPreference.setSummary("Select a gesture tutorial step.");
        launchTutorialStepMenuPreference.setOnPreferenceClickListener(preference -> {
            startActivity(launchSandboxIntent.putExtra("use_tutorial_menu", true));
            return true;
        });
        launchTutorialStepMenuPreference.setIntent(
                new Intent(launchSandboxIntent).putExtra("use_tutorial_menu", true));

        sandboxCategory.addPreference(launchTutorialStepMenuPreference);
        Preference launchOnboardingTutorialPreference = new Preference(context);
        launchOnboardingTutorialPreference.setKey("launchOnboardingTutorial");
        launchOnboardingTutorialPreference.setTitle("Launch Onboarding Tutorial");
        launchOnboardingTutorialPreference.setSummary("Learn the basic navigation gestures.");
        launchOnboardingTutorialPreference.setOnPreferenceClickListener(preference -> {
            startActivity(launchSandboxIntent
        launchTutorialStepMenuPreference.setIntent(new Intent(launchSandboxIntent)
                .putExtra("use_tutorial_menu", false)
                .putExtra("tutorial_steps",
                        new String[] {
                                "HOME_NAVIGATION",
                                "BACK_NAVIGATION",
                                "OVERVIEW_NAVIGATION"}));
            return true;
        });

        sandboxCategory.addPreference(launchOnboardingTutorialPreference);
        Preference launchBackTutorialPreference = new Preference(context);
        launchBackTutorialPreference.setKey("launchBackTutorial");
        launchBackTutorialPreference.setTitle("Launch Back Tutorial");
        launchBackTutorialPreference.setSummary("Learn how to use the Back gesture");
        launchBackTutorialPreference.setOnPreferenceClickListener(preference -> {
            startActivity(launchSandboxIntent
        launchBackTutorialPreference.setIntent(new Intent(launchSandboxIntent)
                    .putExtra("use_tutorial_menu", false)
                    .putExtra("tutorial_steps", new String[] {"BACK_NAVIGATION"}));
            return true;
        });

        sandboxCategory.addPreference(launchBackTutorialPreference);
        Preference launchHomeTutorialPreference = new Preference(context);
        launchHomeTutorialPreference.setKey("launchHomeTutorial");
        launchHomeTutorialPreference.setTitle("Launch Home Tutorial");
        launchHomeTutorialPreference.setSummary("Learn how to use the Home gesture");
        launchHomeTutorialPreference.setOnPreferenceClickListener(preference -> {
            startActivity(launchSandboxIntent
        launchHomeTutorialPreference.setIntent(new Intent(launchSandboxIntent)
                    .putExtra("use_tutorial_menu", false)
                    .putExtra("tutorial_steps", new String[] {"HOME_NAVIGATION"}));
            return true;
        });

        sandboxCategory.addPreference(launchHomeTutorialPreference);
        Preference launchOverviewTutorialPreference = new Preference(context);
        launchOverviewTutorialPreference.setKey("launchOverviewTutorial");
        launchOverviewTutorialPreference.setTitle("Launch Overview Tutorial");
        launchOverviewTutorialPreference.setSummary("Learn how to use the Overview gesture");
        launchOverviewTutorialPreference.setOnPreferenceClickListener(preference -> {
            startActivity(launchSandboxIntent
        launchOverviewTutorialPreference.setIntent(new Intent(launchSandboxIntent)
                    .putExtra("use_tutorial_menu", false)
                    .putExtra("tutorial_steps", new String[] {"OVERVIEW_NAVIGATION"}));
            return true;
        });

        sandboxCategory.addPreference(launchOverviewTutorialPreference);
        Preference launchSecondaryDisplayPreference = new Preference(context);
        launchSecondaryDisplayPreference.setKey("launchSecondaryDisplay");
        launchSecondaryDisplayPreference.setTitle("Launch Secondary Display");
        launchSecondaryDisplayPreference.setSummary("Launch secondary display activity");
        launchSecondaryDisplayPreference.setOnPreferenceClickListener(preference -> {
            startActivity(new Intent(context, SecondaryDisplayLauncher.class));
            return true;
        });
        sandboxCategory.addPreference(launchSecondaryDisplayPreference);
        launchSecondaryDisplayPreference.setIntent(
                new Intent(context, SecondaryDisplayLauncher.class));

    }

    private void addOnboardingPrefsCatergory() {
+20 −28
Original line number Diff line number Diff line
@@ -19,24 +19,23 @@ package com.android.launcher3.uioverrides.flags;
import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD;
import static com.android.launcher3.uioverrides.flags.FlagsFactory.TEAMFOOD_FLAG;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Process;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import androidx.preference.PreferenceDataStore;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;

import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;

import java.util.List;
import java.util.Set;
@@ -44,12 +43,13 @@ import java.util.Set;
/**
 * Dev-build only UI allowing developers to toggle flag settings. See {@link FeatureFlags}.
 */
public final class FlagTogglerPrefUi {
public final class FlagTogglerPrefUi implements ActivityLifecycleCallbacksAdapter {

    private static final String TAG = "FlagTogglerPrefFrag";

    private final PreferenceFragmentCompat mFragment;
    private final View mFlagsApplyButton;
    private final Context mContext;

    private final PreferenceDataStore mDataStore = new PreferenceDataStore() {

        @Override
@@ -64,9 +64,17 @@ public final class FlagTogglerPrefUi {
        }
    };

    public FlagTogglerPrefUi(PreferenceFragmentCompat fragment) {
        mFragment = fragment;
        mContext = fragment.getActivity();
    public FlagTogglerPrefUi(Activity activity, View flagsApplyButton) {
        mFlagsApplyButton = flagsApplyButton;
        mContext = mFlagsApplyButton.getContext();
        activity.registerActivityLifecycleCallbacks(this);

        mFlagsApplyButton.setOnClickListener(v -> {
            FlagsFactory.getSharedPreferences().edit().commit();
            Log.e(TAG,
                    "Killing launcher process " + Process.myPid() + " to apply new flag values");
            System.exit(0);
        });
    }

    public void applyTo(PreferenceGroup parent) {
@@ -137,27 +145,11 @@ public final class FlagTogglerPrefUi {
    }

    private void updateMenu() {
        mFragment.setHasOptionsMenu(anyChanged());
        mFragment.getActivity().invalidateOptionsMenu();
        mFlagsApplyButton.setVisibility(anyChanged() ? View.VISIBLE : View.INVISIBLE);
    }

    public void onCreateOptionsMenu(Menu menu) {
        if (anyChanged()) {
            menu.add(0, R.id.menu_apply_flags, 0, "Apply")
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        }
    }

    public void onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.menu_apply_flags) {
            FlagsFactory.getSharedPreferences().edit().commit();
            Log.e(TAG,
                    "Killing launcher process " + Process.myPid() + " to apply new flag values");
            System.exit(0);
        }
    }

    public void onStop() {
    @Override
    public void onActivityStopped(Activity activity) {
        if (anyChanged()) {
            Toast.makeText(mContext, "Flag won't be applied until you restart launcher",
                    Toast.LENGTH_LONG).show();
+26 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:showDividers="middle">

    <EditText
        android:id="@+id/filter_box"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="@dimen/developer_options_filter_margins"
        android:hint="@string/developer_options_filter_hint"
        android:inputType="text"
        android:maxLines="1"
        android:imeOptions="actionDone"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:text="Apply"
        android:visibility="invisible"
        android:id="@+id/flag_apply_btn" />
</LinearLayout>
 No newline at end of file
+2 −19
Original line number Diff line number Diff line
@@ -2,23 +2,6 @@
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/filter_box"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="@dimen/developer_options_filter_margins"
        android:hint="@string/developer_options_filter_hint"
        android:visibility="gone"
        android:inputType="text"
        android:maxLines="1"
        android:imeOptions="actionDone"
        />

    <FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@android:id/list_container"/>
</LinearLayout>
 No newline at end of file
+0 −6
Original line number Diff line number Diff line
@@ -58,7 +58,6 @@ import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.os.TransactionTooLargeException;
import android.provider.Settings;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@@ -168,11 +167,6 @@ public final class Utilities {
        return nightMode == Configuration.UI_MODE_NIGHT_YES;
    }

    public static boolean isDevelopersOptionsEnabled(Context context) {
        return Settings.Global.getInt(context.getApplicationContext().getContentResolver(),
                        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
    }

    private static boolean sIsRunningInTestHarness = ActivityManager.isRunningInTestHarness();

    public static boolean isRunningInTestHarness() {
Loading