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

Commit 9c1fcf99 authored by Fan Zhang's avatar Fan Zhang
Browse files

Move system update preference from device_info to system.

In order to move the preference and its logic cleanly, created a
controller object that encapsulates the preference/click handler.

Bug: 31801428
Test: RunSettingsRoboTests
Change-Id: I332384e20fbf0e21d2f3becb531d97b20f7f7ef1
parent 8fdb96e3
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -25,4 +25,13 @@
        <intent android:action="android.settings.SYSTEM_UPDATE_SETTINGS"/>
    </com.android.settings.dashboard.DashboardTilePreference>

    <com.android.settings.dashboard.DashboardTilePreference
        android:key="additional_system_update_settings"
        android:title="@string/additional_system_update_settings_list_item_title"
        android:order="-31">
        <intent android:action="android.intent.action.MAIN"
                android:targetPackage="@string/additional_system_update"
                android:targetClass="@string/additional_system_update_menu"/>
    </com.android.settings.dashboard.DashboardTilePreference>

</PreferenceScreen>
 No newline at end of file
+14 −59
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.SELinux;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -31,13 +30,15 @@ import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.telephony.CarrierConfigManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.deviceinfo.SystemUpdatePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Index;
import com.android.settings.search.Indexable;
@@ -56,7 +57,6 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment implements In

    private static final String KEY_MANUAL = "manual";
    private static final String KEY_REGULATORY_INFO = "regulatory_info";
    private static final String KEY_SYSTEM_UPDATE_SETTINGS = "system_update_settings";
    private static final String PROPERTY_URL_SAFETYLEGAL = "ro.url.safetylegal";
    private static final String PROPERTY_SELINUX_STATUS = "ro.build.selinux";
    private static final String KEY_KERNEL_VERSION = "kernel_version";
@@ -66,7 +66,6 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment implements In
    private static final String KEY_BASEBAND_VERSION = "baseband_version";
    private static final String KEY_FIRMWARE_VERSION = "firmware_version";
    private static final String KEY_SECURITY_PATCH = "security_patch";
    private static final String KEY_UPDATE_SETTING = "additional_system_update_settings";
    private static final String KEY_EQUIPMENT_ID = "fcc_equipment_id";
    private static final String PROPERTY_EQUIPMENT_ID = "ro.ril.fccid";
    private static final String KEY_DEVICE_FEEDBACK = "device_feedback";
@@ -77,6 +76,8 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment implements In
    long[] mHits = new long[3];
    int mDevHitCountdown;
    Toast mDevHitToast;
    private SystemUpdatePreferenceController mSystemUpdatePreferenceController;
    private DashboardFeatureProvider mDashboardFeatureProvider;

    private UserManager mUm;

@@ -98,7 +99,11 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment implements In
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        mUm = UserManager.get(getActivity());
        final Activity activity = getActivity();
        mUm = UserManager.get(activity);
        mSystemUpdatePreferenceController = new SystemUpdatePreferenceController(activity, mUm);
        mDashboardFeatureProvider = FeatureFactory.getFactory(activity)
                .getDashboardFeatureProvider(activity);

        addPreferencesFromResource(R.xml.device_info_settings);

@@ -153,23 +158,7 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment implements In
         * Settings is a generic app and should not contain any device-specific
         * info.
         */
        final Activity act = getActivity();

        // These are contained by the root preference screen
        PreferenceGroup parentPreference = getPreferenceScreen();

        if (mUm.isAdminUser()) {
            Utils.updatePreferenceToSpecificActivityOrRemove(act, parentPreference,
                    KEY_SYSTEM_UPDATE_SETTINGS,
                    Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
        } else {
            // Remove for secondary users
            removePreference(KEY_SYSTEM_UPDATE_SETTINGS);
        }

        // Read platform settings for additional system update setting
        removePreferenceIfBoolFalse(KEY_UPDATE_SETTING,
                R.bool.config_additional_system_update_setting_enable);
        mSystemUpdatePreferenceController.displayPreference(getPreferenceScreen());

        // Remove manual entry if none present.
        removePreferenceIfBoolFalse(KEY_MANUAL, R.bool.config_show_manual);
@@ -278,38 +267,11 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment implements In
            }
        } else if (preference.getKey().equals(KEY_DEVICE_FEEDBACK)) {
            sendFeedback();
        } else if(preference.getKey().equals(KEY_SYSTEM_UPDATE_SETTINGS)) {
            CarrierConfigManager configManager =
                    (CarrierConfigManager) getSystemService(Context.CARRIER_CONFIG_SERVICE);
            PersistableBundle b = configManager.getConfig();
            if (b != null && b.getBoolean(CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL)) {
                ciActionOnSysUpdate(b);
            }
        }
        mSystemUpdatePreferenceController.handlePreferenceTreeClick(preference);
        return super.onPreferenceTreeClick(preference);
    }

    /**
     * Trigger client initiated action (send intent) on system update
     */
    private void ciActionOnSysUpdate(PersistableBundle b) {
        String intentStr = b.getString(CarrierConfigManager.
                KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING);
        if (!TextUtils.isEmpty(intentStr)) {
            String extra = b.getString(CarrierConfigManager.
                    KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING);
            String extraVal = b.getString(CarrierConfigManager.
                    KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING);

            Intent intent = new Intent(intentStr);
            if (!TextUtils.isEmpty(extra)) {
                intent.putExtra(extra, extraVal);
            }
            Log.d(LOG_TAG, "ciActionOnSysUpdate: broadcasting intent " + intentStr +
                    " with extra " + extra + ", " + extraVal);
            getActivity().getApplicationContext().sendBroadcast(intent);
        }
    }

    private void removePreferenceIfPropertyMissing(PreferenceGroup preferenceGroup,
            String preference, String property ) {
@@ -434,15 +396,8 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment implements In
                if (TextUtils.isEmpty(DeviceInfoUtils.getFeedbackReporterPackage(context))) {
                    keys.add(KEY_DEVICE_FEEDBACK);
                }
                final UserManager um = UserManager.get(context);
                // TODO: system update needs to be fixed for non-owner user b/22760654
                if (!um.isAdminUser()) {
                    keys.add(KEY_SYSTEM_UPDATE_SETTINGS);
                }
                if (!context.getResources().getBoolean(
                        R.bool.config_additional_system_update_setting_enable)) {
                    keys.add(KEY_UPDATE_SETTING);
                }
                new SystemUpdatePreferenceController(context, UserManager.get(context))
                        .updateNonIndexableKeys(keys);
                return keys;
            }

+147 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.deviceinfo;

import android.content.Context;
import android.content.Intent;
import android.os.PersistableBundle;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.CarrierConfigManager;
import android.text.TextUtils;
import android.util.Log;

import com.android.settings.R;
import com.android.settings.Utils;

import java.util.List;

import static android.content.Context.CARRIER_CONFIG_SERVICE;

public class SystemUpdatePreferenceController {

    private static final String TAG = "SysUpdatePrefContr";

    static final String KEY_SYSTEM_UPDATE_SETTINGS = "system_update_settings";
    static final String KEY_UPDATE_SETTING = "additional_system_update_settings";

    private final Context mContext;
    private final UserManager mUm;

    public SystemUpdatePreferenceController(Context context, UserManager um) {
        mContext = context;
        mUm = um;
    }

    /**
     * Displays preference in this controller.
     */
    public void displayPreference(PreferenceScreen screen) {
        if (isAvailable(mContext, KEY_SYSTEM_UPDATE_SETTINGS)) {
            Utils.updatePreferenceToSpecificActivityOrRemove(mContext, screen,
                    KEY_SYSTEM_UPDATE_SETTINGS,
                    Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
        } else {
            removePreference(screen, KEY_SYSTEM_UPDATE_SETTINGS);
        }

        if (!isAvailable(mContext, KEY_UPDATE_SETTING)) {
            removePreference(screen, KEY_UPDATE_SETTING);
        }
    }

    /**
     * Updates non-indexable keys for search provider.
     *
     * Called by SearchIndexProvider#getNonIndexableKeys
     */
    public void updateNonIndexableKeys(List<String> keys) {
        // TODO: system update needs to be fixed for non-owner user b/22760654
        if (!isAvailable(mContext, KEY_SYSTEM_UPDATE_SETTINGS)) {
            keys.add(KEY_SYSTEM_UPDATE_SETTINGS);
        }
        if (!isAvailable(mContext, KEY_UPDATE_SETTING)) {
            keys.add(KEY_UPDATE_SETTING);
        }
    }

    /**
     * Handles preference tree click
     *
     * @param preference the preference being clicked
     * @return true if click is handled
     */
    public boolean handlePreferenceTreeClick(Preference preference) {
        if (KEY_SYSTEM_UPDATE_SETTINGS.equals(preference.getKey())) {
            CarrierConfigManager configManager =
                    (CarrierConfigManager) mContext.getSystemService(CARRIER_CONFIG_SERVICE);
            PersistableBundle b = configManager.getConfig();
            if (b != null && b.getBoolean(CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL)) {
                ciActionOnSysUpdate(b);
            }
        }
        // always return false here because this handler does not want to block other handlers.
        return false;
    }

    /**
     * Whether a preference should be available on screen.
     */
    private boolean isAvailable(Context context, String key) {
        switch (key) {
            case KEY_SYSTEM_UPDATE_SETTINGS:
                return mUm.isAdminUser();
            case KEY_UPDATE_SETTING:
                return context.getResources().getBoolean(
                        R.bool.config_additional_system_update_setting_enable);
            default:
                return false;
        }
    }

    /**
     * Removes preference from screen.
     */
    private void removePreference(PreferenceScreen screen, String key) {
        Preference pref = screen.findPreference(key);
        if (pref != null) {
            screen.removePreference(pref);
        }
    }

    /**
     * Trigger client initiated action (send intent) on system update
     */
    private void ciActionOnSysUpdate(PersistableBundle b) {
        String intentStr = b.getString(CarrierConfigManager.
                KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING);
        if (!TextUtils.isEmpty(intentStr)) {
            String extra = b.getString(CarrierConfigManager.
                    KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING);
            String extraVal = b.getString(CarrierConfigManager.
                    KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING);

            Intent intent = new Intent(intentStr);
            if (!TextUtils.isEmpty(extra)) {
                intent.putExtra(extra, extraVal);
            }
            Log.d(TAG, "ciActionOnSysUpdate: broadcasting intent " + intentStr +
                    " with extra " + extra + ", " + extraVal);
            mContext.getApplicationContext().sendBroadcast(intent);
        }
    }
}
+11 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.settings.system;

import android.content.Context;
import android.os.Bundle;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;

@@ -24,16 +25,17 @@ import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.DashboardTilePreference;
import com.android.settings.deviceinfo.SystemUpdatePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;

import java.util.List;

public class SystemDashboardFragment extends SettingsPreferenceFragment implements
        Preference.OnPreferenceClickListener {
public class SystemDashboardFragment extends SettingsPreferenceFragment {

    private DashboardFeatureProvider mDashboardFeatureProvider;
    private SystemUpdatePreferenceController mSystemUpdatePreferenceController;

    @Override
    public int getMetricsCategory() {
@@ -45,19 +47,23 @@ public class SystemDashboardFragment extends SettingsPreferenceFragment implemen
        super.onAttach(context);
        mDashboardFeatureProvider =
                FeatureFactory.getFactory(context).getDashboardFeatureProvider(context);
        mSystemUpdatePreferenceController =
                new SystemUpdatePreferenceController(context, UserManager.get(context));
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        super.onCreatePreferences(savedInstanceState, rootKey);
        addPreferencesFromResource(R.xml.system_dashboard_fragment);
        mSystemUpdatePreferenceController.displayPreference(getPreferenceScreen());
        addDashboardCategoryAsPreference();
    }

    @Override
    public boolean onPreferenceClick(Preference preference) {
        // Needed to enable preference click ripple
        return false;
    public boolean onPreferenceTreeClick(Preference preference) {
        final boolean handled =
                mSystemUpdatePreferenceController.handlePreferenceTreeClick(preference);
        return handled || super.onPreferenceTreeClick(preference);
    }

    /**
+102 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.deviceinfo;

import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;

import com.android.settings.R;
import com.android.settings.TestConfig;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import java.util.ArrayList;
import java.util.List;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SystemUpdatePreferenceControllerTest {

    @Mock(answer = RETURNS_DEEP_STUBS)
    private Context mContext;
    @Mock
    private UserManager mUserManager;
    @Mock(answer = RETURNS_DEEP_STUBS)
    private PreferenceScreen mScreen;

    private SystemUpdatePreferenceController mController;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mController = new SystemUpdatePreferenceController(mContext, mUserManager);
    }

    @Test
    public void updateNonIndexable_bothAvailable_shouldNotUpdate() {
        final List<String> keys = new ArrayList<>();
        when(mUserManager.isAdminUser()).thenReturn(true);
        when(mContext.getResources().getBoolean(
                R.bool.config_additional_system_update_setting_enable))
                .thenReturn(true);

        mController.updateNonIndexableKeys(keys);

        assertThat(keys).isEmpty();
    }

    @Test
    public void updateNonIndexable_nothingAvailable_shouldUpdateWith2Prefs() {
        final List<String> keys = new ArrayList<>();

        mController.updateNonIndexableKeys(keys);

        assertThat(keys.size()).isEqualTo(2);
    }

    @Test
    public void displayPrefs_nothingAvailable_shouldNotDisplay() {
        mController.displayPreference(mScreen);

        verify(mScreen, times(2)).removePreference(any(Preference.class));
    }

    @Test
    public void displayPrefs_oneAvailable_shouldDisplayOne() {
        when(mContext.getResources().getBoolean(
                R.bool.config_additional_system_update_setting_enable))
                .thenReturn(true);

        mController.displayPreference(mScreen);

        verify(mScreen).removePreference(any(Preference.class));
    }
}