Rearrange Car Settings

For the most part, rearranging the Settings hierarchy is relatively straightforward and typically consists of moving the relevant preference and PreferenceController to a different XML file. If the PreferenceController uses use(...), be sure to remove it from the previous SettingsFragment and add it to the new SettingsFragment.

This page provides examples for reordering Settings to review situations that may occur.

Move a basic preference

This example explains how to move a preference from one preference screen to another, in which the preference has just a default preference controller. In this example, you move the Units preference from the Homepage preference screen into the System preference screen. To do so, move following XML from homepage_fragment.xml into the appropriate location in system_settings_fragment.xml:

<Preference
        android:icon="@drawable/ic_settings_units"
        android:key="@string/pk_units_settings_entry"
        android:title="@string/units_settings"
        settings:controller="com.android.car.settings.common.DefaultRestrictionsPreferenceController">
        <intent android:targetPackage="com.android.car.settings"
            android:targetClass="com.android.car.settings.common.CarSettingActivities$UnitsSettingsActivity"/>
    </Preference>

Move a preference that uses use(...)

Consider the following more complex example that moves all the preferences in the Data Warning & Limit fragment up one level into the Data Usage fragment, which updates DataWarningAndLimitFragment.java to include the use method to pass information into the preference controllers after construction.

  1. Move the relevant XML to the desired location in data_usage_fragment.xml:
    <Preference
            android:key="@string/pk_data_usage_cycle"
            android:title="@string/app_usage_cycle"
            settings:controller="com.android.car.settings.datausage.CycleResetDayOfMonthPickerPreferenceController"/>
        <com.android.car.settings.common.LogicalPreferenceGroup
            android:key="@string/pk_data_warning_group"
            settings:controller="com.android.car.settings.datausage.DataWarningPreferenceController">
            <SwitchPreference
                android:key="@string/pk_data_set_warning"
                android:title="@string/set_data_warning"/>
            <Preference
                android:key="@string/pk_data_warning"
                android:title="@string/data_warning"/>
        </com.android.car.settings.common.LogicalPreferenceGroup>
        <com.android.car.settings.common.LogicalPreferenceGroup
            android:key="@string/pk_data_limit_group"
            settings:controller="com.android.car.settings.datausage.DataLimitPreferenceController">
            <SwitchPreference
                android:key="@string/pk_data_set_limit"
                android:title="@string/set_data_limit"/>
            <Preference
                android:key="@string/pk_data_limit"
                android:title="@string/data_limit"/>
        </com.android.car.settings.common.LogicalPreferenceGroup>
  2. In DataWarningAndLimitFragment.java, determine how the use method is used.
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    
        mPolicyEditor = new NetworkPolicyEditor(NetworkPolicyManager.from(context));
        mNetworkTemplate = getArguments().getParcelable(
                NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE);
        if (mNetworkTemplate == null) {
            mTelephonyManager = context.getSystemService(TelephonyManager.class);
            mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
            mNetworkTemplate = DataUsageUtils.getMobileNetworkTemplate(mTelephonyManager,
                    DataUsageUtils.getDefaultSubscriptionId(mSubscriptionManager));
        }
    
        // Loads the current policies to the policy editor cache.
        mPolicyEditor.read();
    
        List<DataWarningAndLimitBasePreferenceController> preferenceControllers =
                Arrays.asList(
                       use(CycleResetDayOfMonthPickerPreferenceController.class,
                                R.string.pk_data_usage_cycle),
                       use(DataWarningPreferenceController.class, R.string.pk_data_warning_group),
                       use(DataLimitPreferenceController.class, R.string.pk_data_limit_group));
    
        for (DataWarningAndLimitBasePreferenceController preferenceController :
                preferenceControllers) {
            preferenceController.setNetworkPolicyEditor(mPolicyEditor);
            preferenceController.setNetworkTemplate(mNetworkTemplate);
        }
    }

    In this case, the use method sets the network policy editor and network template for the preference controllers. Because this example moves all the preferences and all the code in the onAttach method is relevant to setting these preference parameters, it would be appropriate to copy over the entire method contents into the new fragment. However, this varies depending on the specific preference. You need to also move over the relevant instance variables.

    However, there is a complication. The original fragment expected NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE to be passed in as an argument, which should come in from the intent to the activity (when provided).

    To get this needed information, either create a newInstance method and pass in the template when present (otherwise pass in null) and then update the activity for the DataUsageFragment or get the intent information directly in the onAttach method by using getActivity().getIntent(). In either case, you can pass in the needed information for this method as you did above.

  3. Identify any other dependencies or expected intent actions in the old fragment before cleaning up the old fragments and XML files. In this case, an overlay config value points to the old activity, which must be updated to point to the correct activity.

Add a preference screen to the hierarchy

To add a new preference screen to the hierarchy, see Add Car Settings.

After creating the new preference screen, use the examples above to rearrange the preference hierarchy as desired.