[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
This commit is contained in:
tom hsu
2021-06-03 11:46:30 +08:00
parent b857491c48
commit f7811dfd09
6 changed files with 253 additions and 5 deletions

View File

@@ -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<Integer, Preference> 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);

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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);
}
}