From f7811dfd09374a2dbae3f1268a726a47e5595ef0 Mon Sep 17 00:00:00 2001 From: tom hsu Date: Thu, 3 Jun 2021 11:46:30 +0800 Subject: [PATCH] [Settings] Disable gear button if user is not admin. - Mobile settings include many settings which second user shall not modify, so make gear button disabled to avoid second user want to try. Bug: 184303943 Test: Maunal test passeded Test: atest passed. Change-Id: Ic04fa71772df4ac424965ad2ca95733b1e15d6a7 --- .../SubscriptionsPreferenceController.java | 12 ++- .../settings/widget/GearPreference.java | 16 +++- .../widget/MutableGearPreference.java | 57 +++++++++++++ ...SubscriptionsPreferenceControllerTest.java | 5 ++ .../settings/widget/GearPreferenceTest.java | 84 +++++++++++++++++++ .../widget/MutableGearPreferenceTest.java | 84 +++++++++++++++++++ 6 files changed, 253 insertions(+), 5 deletions(-) create mode 100644 src/com/android/settings/widget/MutableGearPreference.java create mode 100644 tests/unit/src/com/android/settings/widget/GearPreferenceTest.java create mode 100644 tests/unit/src/com/android/settings/widget/MutableGearPreferenceTest.java diff --git a/src/com/android/settings/network/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java index 2d23f1f618e..e0f20cdb583 100644 --- a/src/com/android/settings/network/SubscriptionsPreferenceController.java +++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java @@ -29,6 +29,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.graphics.drawable.Drawable; import android.net.wifi.WifiManager; +import android.os.UserManager; import android.provider.Settings; import android.telephony.ServiceState; import android.telephony.SignalStrength; @@ -55,7 +56,7 @@ import com.android.settings.network.telephony.MobileNetworkActivity; import com.android.settings.network.telephony.MobileNetworkUtils; import com.android.settings.network.telephony.SignalStrengthListener; import com.android.settings.network.telephony.TelephonyDisplayInfoListener; -import com.android.settings.widget.GearPreference; +import com.android.settings.widget.MutableGearPreference; import com.android.settings.wifi.WifiPickerTrackerHelper; import com.android.settingslib.SignalIcon.MobileIconGroup; import com.android.settingslib.core.AbstractPreferenceController; @@ -115,7 +116,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl // Map of subscription id to Preference private Map mSubscriptionPreferences; private int mStartOrder; - private GearPreference mSubsGearPref; + private MutableGearPreference mSubsGearPref; private Config mConfig = null; private SubsPrefCtrlInjector mSubsPrefCtrlInjector; private TelephonyDisplayInfo mTelephonyDisplayInfo = @@ -238,15 +239,20 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl } if (mSubsGearPref == null) { mPreferenceGroup.removeAll(); - mSubsGearPref = new GearPreference(mContext, null); + mSubsGearPref = new MutableGearPreference(mContext, null); mSubsGearPref.setOnPreferenceClickListener(preference -> { connectCarrierNetwork(); return true; }); + mSubsGearPref.setOnGearClickListener(p -> startMobileNetworkActivity(mContext, subInfo.getSubscriptionId())); } + if (!(mContext.getSystemService(UserManager.class)).isAdminUser()) { + mSubsGearPref.setGearEnabled(false); + } + mSubsGearPref.setTitle(SubscriptionUtil.getUniqueSubscriptionDisplayName( subInfo, mContext)); mSubsGearPref.setOrder(mStartOrder); diff --git a/src/com/android/settings/widget/GearPreference.java b/src/com/android/settings/widget/GearPreference.java index 0a301006698..82bc1f0c203 100644 --- a/src/com/android/settings/widget/GearPreference.java +++ b/src/com/android/settings/widget/GearPreference.java @@ -29,7 +29,8 @@ import com.android.settingslib.RestrictedPreference; * A preference with a Gear on the side */ public class GearPreference extends RestrictedPreference implements View.OnClickListener { - + // Default true for gear available even if the preference itself is disabled. + protected boolean mGearState = true; private OnGearClickListener mOnGearClickListener; public GearPreference(Context context, AttributeSet attrs) { @@ -41,6 +42,16 @@ public class GearPreference extends RestrictedPreference implements View.OnClick notifyChanged(); } + /** Sets state of gear button. */ + public void setGearEnabled(boolean enabled) { + mGearState = enabled; + } + + /** Gets state of gear button. */ + public boolean isGearEnabled() { + return mGearState; + } + @Override protected int getSecondTargetResId() { return R.layout.preference_widget_gear; @@ -62,7 +73,8 @@ public class GearPreference extends RestrictedPreference implements View.OnClick gear.setVisibility(View.GONE); gear.setOnClickListener(null); } - gear.setEnabled(true); // Make gear available even if the preference itself is disabled. + // Make gear available even if the preference itself is disabled. + gear.setEnabled(mGearState); } @Override diff --git a/src/com/android/settings/widget/MutableGearPreference.java b/src/com/android/settings/widget/MutableGearPreference.java new file mode 100644 index 00000000000..b0804ebc2db --- /dev/null +++ b/src/com/android/settings/widget/MutableGearPreference.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 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.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.ImageView; + +import androidx.preference.PreferenceViewHolder; + +import com.android.settings.R; +import com.android.settingslib.utils.ColorUtil; + +/** A preference with a Gear on the side and mutable Gear color. */ +public class MutableGearPreference extends GearPreference { + private static final int VALUE_ENABLED_ALPHA = 255; + + private ImageView mGear; + private Context mContext; + private int mDisabledAlphaValue; + + public MutableGearPreference(Context context, AttributeSet attrs) { + super(context, attrs); + mContext = context; + mDisabledAlphaValue = (int) (ColorUtil.getDisabledAlpha(context) * VALUE_ENABLED_ALPHA); + } + + @Override + public void setGearEnabled(boolean enabled) { + if (mGear != null) { + mGear.setEnabled(enabled); + mGear.setImageAlpha(enabled ? VALUE_ENABLED_ALPHA : mDisabledAlphaValue); + } + mGearState = enabled; + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + mGear = (ImageView) holder.findViewById(R.id.settings_button); + setGearEnabled(mGearState); + } +} diff --git a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java index 0ef44eef270..fc18ce71268 100644 --- a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java @@ -40,6 +40,7 @@ import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.os.Looper; +import android.os.UserManager; import android.provider.Settings; import android.telephony.ServiceState; import android.telephony.SignalStrength; @@ -81,6 +82,8 @@ import java.util.List; public class SubscriptionsPreferenceControllerTest { private static final String KEY = "preference_group"; + @Mock + private UserManager mUserManager; @Mock private SubscriptionManager mSubscriptionManager; @Mock @@ -121,10 +124,12 @@ public class SubscriptionsPreferenceControllerTest { when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager); when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager); when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); when(mConnectivityManager.getActiveNetwork()).thenReturn(mActiveNetwork); when(mConnectivityManager.getNetworkCapabilities(mActiveNetwork)) .thenReturn(mNetworkCapabilities); + when(mUserManager.isAdminUser()).thenReturn(true); when(mLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry); mPreferenceManager = new PreferenceManager(mContext); diff --git a/tests/unit/src/com/android/settings/widget/GearPreferenceTest.java b/tests/unit/src/com/android/settings/widget/GearPreferenceTest.java new file mode 100644 index 00000000000..a47eade61c3 --- /dev/null +++ b/tests/unit/src/com/android/settings/widget/GearPreferenceTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2021 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.widget; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; + +import androidx.preference.PreferenceViewHolder; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.settings.testutils.ResourcesUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unittest for GearPreference */ +@RunWith(AndroidJUnit4.class) +public class GearPreferenceTest { + @Mock + private GearPreference.OnGearClickListener mOnGearClickListener; + + private Context mContext = ApplicationProvider.getApplicationContext(); + private GearPreference mGearPreference; + private PreferenceViewHolder mViewHolder; + private View mGearView; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mGearPreference = + new GearPreference(mContext, null); + int layoutId = ResourcesUtils.getResourcesId(mContext, "layout", "preference_widget_gear"); + PreferenceViewHolder holder = + PreferenceViewHolder.createInstanceForTests( + LayoutInflater.from(ApplicationProvider.getApplicationContext()) + .inflate(layoutId, null)); + mViewHolder = spy(holder); + mGearView = new View(mContext, null); + int gearId = ResourcesUtils.getResourcesId(mContext, "id", "settings_button"); + when(mViewHolder.findViewById(gearId)).thenReturn(mGearView); + } + + @Test + public void onBindViewHolder_gearIsVisible() { + mGearPreference.setOnGearClickListener(mOnGearClickListener); + + mGearPreference.onBindViewHolder(mViewHolder); + + assertThat(mGearView.getVisibility()).isEqualTo(View.VISIBLE); + } + + @Test + public void onBindViewHolder_gearIsGone() { + mGearPreference.setOnGearClickListener(null); + + mGearPreference.onBindViewHolder(mViewHolder); + + assertThat(mGearView.getVisibility()).isEqualTo(View.GONE); + } +} diff --git a/tests/unit/src/com/android/settings/widget/MutableGearPreferenceTest.java b/tests/unit/src/com/android/settings/widget/MutableGearPreferenceTest.java new file mode 100644 index 00000000000..44b1d380508 --- /dev/null +++ b/tests/unit/src/com/android/settings/widget/MutableGearPreferenceTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2021 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.widget; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.widget.ImageView; + +import androidx.preference.PreferenceViewHolder; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.settings.testutils.ResourcesUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unittest for MutableGearPreference */ +@RunWith(AndroidJUnit4.class) +public class MutableGearPreferenceTest { + @Mock + private MutableGearPreference.OnGearClickListener mOnGearClickListener; + + private Context mContext = ApplicationProvider.getApplicationContext(); + private MutableGearPreference mMutableGearPreference; + private PreferenceViewHolder mViewHolder; + private ImageView mGearView; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mMutableGearPreference = + new MutableGearPreference(mContext, null); + int layoutId = + ResourcesUtils.getResourcesId(mContext, "layout", "preference_widget_gear"); + PreferenceViewHolder holder = + PreferenceViewHolder.createInstanceForTests( + LayoutInflater.from(ApplicationProvider.getApplicationContext()) + .inflate(layoutId, null)); + mViewHolder = spy(holder); + mGearView = spy(new ImageView(mContext, null)); + int gearId = ResourcesUtils.getResourcesId(mContext, "id", "settings_button"); + when(mViewHolder.findViewById(gearId)).thenReturn(mGearView); + } + + @Test + public void onBindViewHolder_gearChangeAlpha() { + mMutableGearPreference.setGearEnabled(false); + mMutableGearPreference.setOnGearClickListener(mOnGearClickListener); + + mMutableGearPreference.onBindViewHolder(mViewHolder); + + verify(mGearView).setImageAlpha(anyInt()); + } + + private static int getDisabledAlphaValue(Context context) { + TypedValue value = new TypedValue(); + context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, value, true); + return (int) (value.getFloat() * 255); + } +}