From 5af18b2733f98a27d234089374def98e43ea3b1e Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Wed, 25 Nov 2020 16:13:18 +0800 Subject: [PATCH 01/19] Fix robotests failure in connectivity settings Bug: 174212358 Test: make -j42 RunSettingsRoboTests Change-Id: I50baeb18b00f16808dc958d77251a01ba991adf6 (cherry picked from commit e61a5e3bc7e1e79bead1413319db3c356795626f) --- ...AdvancedConnectedDeviceControllerTest.java | 5 ++- ...dConnectedDeviceDashboardFragmentTest.java | 19 +++++----- .../NfcAndPaymentFragmentControllerTest.java | 17 +++++---- .../NfcAndPaymentFragmentTest.java | 22 ++++++++--- .../AndroidBeamPreferenceControllerTest.java | 29 ++++++++------- .../NfcPaymentPreferenceControllerTest.java | 3 ++ .../nfc/NfcPreferenceControllerTest.java | 35 ++++++++++-------- .../settings/nfc/PaymentSettingsTest.java | 4 +- .../testutils/shadow/ShadowNfcAdapter.java | 37 ++++++++++++++++--- 9 files changed, 112 insertions(+), 59 deletions(-) diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java index 974a52b519d..6ae670dc120 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java @@ -34,6 +34,7 @@ import androidx.test.core.content.pm.ApplicationInfoBuilder; import com.android.settings.R; import com.android.settings.nfc.NfcPreferenceController; +import com.android.settings.testutils.shadow.ShadowNfcAdapter; import org.junit.Before; import org.junit.Test; @@ -43,7 +44,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowNfcAdapter; +import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowPackageManager; import org.robolectric.util.ReflectionHelpers; @@ -70,7 +71,7 @@ public class AdvancedConnectedDeviceControllerTest { mContentResolver = mContext.getContentResolver(); mNfcController = new NfcPreferenceController(mContext, NfcPreferenceController.KEY_TOGGLE_NFC); - mShadowNfcAdapter = Shadows.shadowOf(NfcAdapter.getNfcAdapter(mContext)); + mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext)); mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager()); } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java index d6bcb127667..aed3787b0fa 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java @@ -18,7 +18,6 @@ package com.android.settings.connecteddevice; 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.nfc.NfcAdapter; @@ -26,35 +25,38 @@ import android.provider.SearchIndexableResource; import com.android.settings.nfc.AndroidBeamPreferenceController; import com.android.settings.testutils.shadow.ShadowConnectivityManager; +import com.android.settings.testutils.shadow.ShadowNfcAdapter; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.drawer.CategoryKey; 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.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import java.util.List; @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowUserManager.class, - ShadowConnectivityManager.class}) + ShadowConnectivityManager.class, ShadowNfcAdapter.class}) public class AdvancedConnectedDeviceDashboardFragmentTest { private AdvancedConnectedDeviceDashboardFragment mFragment; - @Mock - private NfcAdapter mNfcAdapter; + private Context mContext; + private ShadowNfcAdapter mShadowNfcAdapter; @Before public void setUp() { MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); mFragment = new AdvancedConnectedDeviceDashboardFragment(); + mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext)); } @Test @@ -79,13 +81,10 @@ public class AdvancedConnectedDeviceDashboardFragmentTest { @Test public void testSearchIndexProvider_correctNonIndexables() { - Context context = spy(RuntimeEnvironment.application); - when(context.getApplicationContext()).thenReturn(context); - when(NfcAdapter.getDefaultAdapter(context)).thenReturn(mNfcAdapter); - when(mNfcAdapter.isSecureNfcSupported()).thenReturn(true); + mShadowNfcAdapter.setSecureNfcSupported(true); final List niks = AdvancedConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER - .getNonIndexableKeys(context); + .getNonIndexableKeys(mContext); assertThat(niks).contains(AndroidBeamPreferenceController.KEY_ANDROID_BEAM_SETTINGS); } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java index ffaade3fda3..8acb81cf28c 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java @@ -29,6 +29,7 @@ import android.nfc.NfcManager; import android.os.UserManager; import com.android.settings.R; +import com.android.settings.testutils.shadow.ShadowNfcAdapter; import org.junit.Before; import org.junit.Test; @@ -37,9 +38,12 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowNfcAdapter.class) public class NfcAndPaymentFragmentControllerTest { private NfcAndPaymentFragmentController mController; private Context mContext; @@ -50,29 +54,28 @@ public class NfcAndPaymentFragmentControllerTest { private UserManager mUserManager; @Mock private NfcManager mNfcManager; - @Mock - private NfcAdapter mNfcAdapter; + + private ShadowNfcAdapter mShadowNfcAdapter; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext)); when(mContext.getApplicationContext()).thenReturn(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mNfcManager); - when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter); mController = new NfcAndPaymentFragmentController(mContext, "fakeKey"); - ReflectionHelpers.setField(mController, "mNfcAdapter", mNfcAdapter); } @Test public void getAvailabilityStatus_hasNfc_shouldReturnAvailable() { when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true); when(mUserManager.isAdminUser()).thenReturn(true); - when(mNfcAdapter.isEnabled()).thenReturn(true); + mShadowNfcAdapter.setEnabled(true); assertThat(mController.getAvailabilityStatus()) .isEqualTo(NfcAndPaymentFragmentController.AVAILABLE); @@ -87,14 +90,14 @@ public class NfcAndPaymentFragmentControllerTest { @Test public void getSummary_nfcOn_shouldProvideOnSummary() { - when(mNfcAdapter.isEnabled()).thenReturn(true); + mShadowNfcAdapter.setEnabled(true); assertThat(mController.getSummary().toString()).contains( mContext.getString(R.string.switch_on_text)); } @Test public void getSummary_nfcOff_shouldProvideOffSummary() { - when(mNfcAdapter.isEnabled()).thenReturn(false); + mShadowNfcAdapter.setEnabled(false); assertThat(mController.getSummary().toString()).contains( mContext.getString(R.string.switch_off_text)); } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentTest.java index 46c9cbb2ab0..dea0c7388a0 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentTest.java @@ -22,9 +22,12 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.content.pm.PackageManager; import android.nfc.NfcAdapter; import android.provider.SearchIndexableResource; +import com.android.settings.testutils.shadow.ShadowNfcAdapter; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,16 +35,20 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowNfcAdapter.class) public class NfcAndPaymentFragmentTest { + @Mock + private PackageManager mPackageManager; + private NfcAndPaymentFragment mFragment; private Context mContext; - - @Mock - private NfcAdapter mNfcAdapter; + private ShadowNfcAdapter mShadowNfcAdapter; @Before public void setUp() { @@ -49,6 +56,9 @@ public class NfcAndPaymentFragmentTest { mFragment = new NfcAndPaymentFragment(); mContext = spy(RuntimeEnvironment.application); + mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext)); + + when(mContext.getPackageManager()).thenReturn(mPackageManager); } @Test @@ -64,8 +74,10 @@ public class NfcAndPaymentFragmentTest { @Test public void searchIndexProvider_shouldIndexValidItems() { when(mContext.getApplicationContext()).thenReturn(mContext); - when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter); - when(mNfcAdapter.isSecureNfcSupported()).thenReturn(true); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true); + when(mPackageManager.hasSystemFeature( + PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(true); + mShadowNfcAdapter.setSecureNfcSupported(true); final List niks = NfcAndPaymentFragment.SEARCH_INDEX_DATA_PROVIDER .getNonIndexableKeys(mContext); diff --git a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java index cd70d662022..7e1561863cc 100644 --- a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java @@ -31,6 +31,7 @@ import android.provider.Settings; import androidx.preference.PreferenceScreen; +import com.android.settings.testutils.shadow.ShadowNfcAdapter; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedPreference; @@ -41,19 +42,20 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowNfcAdapter.class) public class AndroidBeamPreferenceControllerTest { Context mContext; @Mock - private NfcAdapter mNfcAdapter; - @Mock - NfcManager mManager; + NfcManager mNfcManager; @Mock private UserManager mUserManager; @Mock @@ -63,18 +65,19 @@ public class AndroidBeamPreferenceControllerTest { private RestrictedPreference mAndroidBeamPreference; private AndroidBeamPreferenceController mAndroidBeamController; + private ShadowNfcAdapter mShadowNfcAdapter; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext)); when(mContext.getApplicationContext()).thenReturn(mContext); when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mManager); + when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mNfcManager); when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext, UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId())).thenReturn(false); - when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter); mAndroidBeamController = new AndroidBeamPreferenceController(mContext, AndroidBeamPreferenceController.KEY_ANDROID_BEAM_SETTINGS); @@ -95,13 +98,13 @@ public class AndroidBeamPreferenceControllerTest { @Test public void isAvailable_hasNfc_shouldReturnTrue() { - when(mNfcAdapter.isEnabled()).thenReturn(true); + mShadowNfcAdapter.setEnabled(true); assertThat(mAndroidBeamController.isAvailable()).isTrue(); } @Test public void isAvailable_noNfcFeature_shouldReturnFalse() { - when(mNfcAdapter.isEnabled()).thenReturn(true); + mShadowNfcAdapter.setEnabled(true); when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM)).thenReturn(false); assertThat(mAndroidBeamController.isAvailable()).isFalse(); } @@ -114,7 +117,7 @@ public class AndroidBeamPreferenceControllerTest { @Test public void isBeamEnable_disAllowBeam_shouldReturnFalse() { - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_OFF); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF); when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext, UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId())).thenReturn(true); @@ -125,7 +128,7 @@ public class AndroidBeamPreferenceControllerTest { @Test public void isBeamEnable_nfcStateOn_shouldReturnTrue() { - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_ON); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_ON); try { mAndroidBeamController.onResume(); } catch (NullPointerException e) { @@ -137,22 +140,22 @@ public class AndroidBeamPreferenceControllerTest { @Test public void isBeamEnable_nfcStateNotOn_shouldReturnFalse() { - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_OFF); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF); mAndroidBeamController.onResume(); assertThat(mAndroidBeamPreference.isEnabled()).isFalse(); - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_ON); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_ON); mAndroidBeamController.onResume(); assertThat(mAndroidBeamPreference.isEnabled()).isFalse(); - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_OFF); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_OFF); mAndroidBeamController.onResume(); assertThat(mAndroidBeamPreference.isEnabled()).isFalse(); } @Test public void updateNonIndexableKeys_available_shouldNotUpdate() { - when(mNfcAdapter.isEnabled()).thenReturn(true); + mShadowNfcAdapter.setEnabled(true); final List keys = new ArrayList<>(); mAndroidBeamController.updateNonIndexableKeys(keys); diff --git a/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java index b69e1727762..026fdeebf9a 100644 --- a/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java @@ -29,6 +29,7 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.nfc.PaymentBackend.PaymentAppInfo; +import com.android.settings.testutils.shadow.ShadowNfcAdapter; import org.junit.Before; import org.junit.Test; @@ -37,10 +38,12 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import java.util.ArrayList; @RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowNfcAdapter.class) public class NfcPaymentPreferenceControllerTest { private static final String PREF_KEY = PaymentSettingsTest.PAYMENT_KEY; diff --git a/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java index 872c7124119..1d0516230a4 100644 --- a/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java @@ -35,6 +35,7 @@ import androidx.preference.SwitchPreference; import com.android.settings.nfc.NfcPreferenceController.NfcSliceWorker; import com.android.settings.nfc.NfcPreferenceController.NfcSliceWorker.NfcUpdateReceiver; +import com.android.settings.testutils.shadow.ShadowNfcAdapter; import org.junit.Before; import org.junit.Test; @@ -43,16 +44,17 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowNfcAdapter.class) public class NfcPreferenceControllerTest { - @Mock - private NfcAdapter mNfcAdapter; @Mock NfcManager mManager; @Mock @@ -63,16 +65,19 @@ public class NfcPreferenceControllerTest { private Context mContext; private SwitchPreference mNfcPreference; private NfcPreferenceController mNfcController; + private ShadowNfcAdapter mShadowNfcAdapter; + private NfcAdapter mNfcAdapter; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext)); + mNfcAdapter = NfcAdapter.getDefaultAdapter(mContext); when(mContext.getApplicationContext()).thenReturn(mContext); when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mManager); - when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter); mNfcController = new NfcPreferenceController(mContext, NfcPreferenceController.KEY_TOGGLE_NFC); @@ -83,7 +88,7 @@ public class NfcPreferenceControllerTest { @Test public void getAvailabilityStatus_hasNfc_shouldReturnAvailable() { - when(mNfcAdapter.isEnabled()).thenReturn(true); + mShadowNfcAdapter.setEnabled(true); assertThat(mNfcController.getAvailabilityStatus()) .isEqualTo(NfcPreferenceController.AVAILABLE); } @@ -98,11 +103,11 @@ public class NfcPreferenceControllerTest { @Test public void isNfcEnable_nfcStateNotTurning_shouldReturnTrue() { mNfcController.displayPreference(mScreen); - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_ON); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_ON); mNfcController.onResume(); assertThat(mNfcPreference.isEnabled()).isTrue(); - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_OFF); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF); mNfcController.onResume(); assertThat(mNfcPreference.isEnabled()).isTrue(); } @@ -110,11 +115,11 @@ public class NfcPreferenceControllerTest { @Test public void isNfcEnable_nfcStateTurning_shouldReturnFalse() { mNfcController.displayPreference(mScreen); - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_ON); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_ON); mNfcController.onResume(); assertThat(mNfcPreference.isEnabled()).isFalse(); - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_OFF); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_OFF); mNfcController.onResume(); assertThat(mNfcPreference.isEnabled()).isFalse(); } @@ -122,29 +127,29 @@ public class NfcPreferenceControllerTest { @Test public void isNfcChecked_nfcStateOn_shouldReturnTrue() { mNfcController.displayPreference(mScreen); - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_ON); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_ON); mNfcController.onResume(); assertThat(mNfcPreference.isChecked()).isTrue(); - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_ON); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_ON); mNfcController.onResume(); assertThat(mNfcPreference.isChecked()).isTrue(); } @Test public void isNfcChecked_nfcStateOff_shouldReturnFalse() { - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_OFF); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF); mNfcController.onResume(); assertThat(mNfcPreference.isChecked()).isFalse(); - when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_OFF); + mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_OFF); mNfcController.onResume(); assertThat(mNfcPreference.isChecked()).isFalse(); } @Test public void updateNonIndexableKeys_available_shouldNotUpdate() { - when(mNfcAdapter.isEnabled()).thenReturn(true); + mShadowNfcAdapter.setEnabled(true); final List keys = new ArrayList<>(); mNfcController.updateNonIndexableKeys(keys); @@ -167,7 +172,7 @@ public class NfcPreferenceControllerTest { mNfcController.setChecked(true); mNfcController.onResume(); - verify(mNfcAdapter).enable(); + assertThat(mNfcAdapter.isEnabled()).isTrue(); } @Test @@ -175,7 +180,7 @@ public class NfcPreferenceControllerTest { mNfcController.setChecked(false); mNfcController.onResume(); - verify(mNfcAdapter).disable(); + assertThat(mNfcAdapter.isEnabled()).isFalse(); } @Test diff --git a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java index 525f3efd3b8..dcf49a2ed9a 100644 --- a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java +++ b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java @@ -33,6 +33,8 @@ import androidx.preference.Preference; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; +import com.android.settings.testutils.shadow.ShadowNfcAdapter; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -48,7 +50,7 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) -@Config(shadows = PaymentSettingsTest.ShadowPaymentBackend.class) +@Config(shadows = {PaymentSettingsTest.ShadowPaymentBackend.class, ShadowNfcAdapter.class}) public class PaymentSettingsTest { static final String PAYMENT_KEY = "nfc_payment"; diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowNfcAdapter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowNfcAdapter.java index fb8c068f3ba..54f665c75d9 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowNfcAdapter.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowNfcAdapter.java @@ -16,6 +16,8 @@ package com.android.settings.testutils.shadow; +import static org.robolectric.shadow.api.Shadow.newInstanceOf; + import android.app.Activity; import android.content.Context; import android.nfc.NfcAdapter; @@ -24,16 +26,18 @@ import android.os.Bundle; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; -import org.robolectric.util.ReflectionHelpers; -import org.robolectric.util.ReflectionHelpers.ClassParameter; /** * Shadow of {@link NfcAdapter}. */ -@Implements(NfcAdapter.class) -public class ShadowNfcAdapter { +@Implements(value = NfcAdapter.class) +public class ShadowNfcAdapter extends org.robolectric.shadows.ShadowNfcAdapter { private static boolean sReaderModeEnabled; + private static Object sNfcAdapter = newInstanceOf("android.nfc.NfcAdapter"); + private boolean mIsNfcEnabled = false; + private int mState = NfcAdapter.STATE_ON; + private boolean mIsSecureNfcSupported = false; @Implementation protected void enableReaderMode(Activity activity, NfcAdapter.ReaderCallback callback, @@ -43,8 +47,7 @@ public class ShadowNfcAdapter { @Implementation protected static NfcAdapter getDefaultAdapter(Context context) { - return ReflectionHelpers.callConstructor( - NfcAdapter.class, ClassParameter.from(Context.class, context)); + return (NfcAdapter) sNfcAdapter; } @Implementation @@ -52,6 +55,28 @@ public class ShadowNfcAdapter { return mIsNfcEnabled; } + public void setEnabled(boolean enable) { + mIsNfcEnabled = enable; + } + + @Implementation + protected int getAdapterState() { + return mState; + } + + public void setAdapterState(int state) { + this.mState = state; + } + + @Implementation + protected boolean isSecureNfcSupported() { + return mIsSecureNfcSupported; + } + + public void setSecureNfcSupported(boolean supported) { + this.mIsSecureNfcSupported = supported; + } + @Implementation protected boolean enable() { mIsNfcEnabled = true; From 92480fc15d5406e6b08c73817dc1c72a5c54a775 Mon Sep 17 00:00:00 2001 From: Benjamin Franz Date: Wed, 6 Jan 2021 15:12:50 +0000 Subject: [PATCH 02/19] Update constructor usage for CompatibilityChangeInfo As we're introducing an overridable flag on CompatibilityChangeInfo, the constructor takes an additional argument that needs to be reflected in these tests. Bug: 174043039 Test: atest SettingsRoboTests Change-Id: Ib5528ded408cb7807e2e3a90e1f99ee1775d566d --- .../compat/PlatformCompatDashboardTest.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java b/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java index 15e9bdaddcc..dffd7fb944a 100644 --- a/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java +++ b/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java @@ -88,14 +88,16 @@ public class PlatformCompatDashboardTest { public void setUp() throws RemoteException, NameNotFoundException { MockitoAnnotations.initMocks(this); mChanges = new CompatibilityChangeInfo[5]; - mChanges[0] = new CompatibilityChangeInfo(1L, "Default_Enabled", 0, 0, false, false, ""); - mChanges[1] = new CompatibilityChangeInfo(2L, "Default_Disabled", 0, 0, true, false, ""); - mChanges[2] = new CompatibilityChangeInfo(3L, "Enabled_Since_SDK_1_1", -1, 1, false, false, - ""); - mChanges[3] = new CompatibilityChangeInfo(4L, "Enabled_Since_SDK_1_2", -1, 1, false, false, - ""); - mChanges[4] = new CompatibilityChangeInfo(5L, "Enabled_Since_SDK_2", -1, 2, false, false, - ""); + mChanges[0] = new CompatibilityChangeInfo( + 1L, "Default_Enabled", 0, 0, false, false, "", false); + mChanges[1] = new CompatibilityChangeInfo( + 2L, "Default_Disabled", 0, 0, true, false, "", false); + mChanges[2] = new CompatibilityChangeInfo( + 3L, "Enabled_Since_SDK_1_1", -1, 1, false, false, "", false); + mChanges[3] = new CompatibilityChangeInfo( + 4L, "Enabled_Since_SDK_1_2", -1, 1, false, false, "", false); + mChanges[4] = new CompatibilityChangeInfo( + 5L, "Enabled_Since_SDK_2", -1, 2, false, false, "", false); when(mPlatformCompat.listUIChanges()).thenReturn(mChanges); when(mPlatformCompat.getOverrideValidator()).thenReturn(mOverrideValidator); // By default, allow any change @@ -208,7 +210,8 @@ public class PlatformCompatDashboardTest { for (int i = 0; i < mChanges.length; ++i) { changesToAdd.add(new CompatibilityChangeInfo(mChanges[i].getId(), mChanges[i].getName(), -1, mChanges[i].getEnableSinceTargetSdk(), mChanges[i].getDisabled(), - mChanges[i].getLoggingOnly(), mChanges[i].getDescription())); + mChanges[i].getLoggingOnly(), mChanges[i].getDescription(), + mChanges[i].getOverridable())); } PreferenceCategory category = mDashboard.createChangeCategoryPreference(changesToAdd, From dfe19770441f11d619e8dd16cd38c0accb948ecf Mon Sep 17 00:00:00 2001 From: Ben Chung Date: Thu, 7 Jan 2021 16:35:02 +0800 Subject: [PATCH 03/19] Accessibility settings interaction controls category restructure, add tap assistance fragment for related accessibility services. Bug: 174829936 Test: atest TapAssistanceFragmentTest, atest AccessibilitySettingsTest Change-Id: I39c4eba8ec807248eb11371fab2466cf7d7553ef --- res/values/strings.xml | 2 + res/xml/accessibility_settings.xml | 29 +++-------- res/xml/accessibility_tap_assistance.xml | 44 ++++++++++++++++ .../accessibility/TapAssistanceFragment.java | 50 +++++++++++++++++++ .../TapAssistanceFragmentTest.java | 49 ++++++++++++++++++ 5 files changed, 152 insertions(+), 22 deletions(-) create mode 100644 res/xml/accessibility_tap_assistance.xml create mode 100644 src/com/android/settings/accessibility/TapAssistanceFragment.java create mode 100644 tests/robotests/src/com/android/settings/accessibility/TapAssistanceFragmentTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index d687357e096..7fd390a08ad 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4950,6 +4950,8 @@ Text and display Interaction controls + + Tap assistance Downloaded apps diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml index 6efd8843ecf..126865cc44b 100644 --- a/res/xml/accessibility_settings.xml +++ b/res/xml/accessibility_settings.xml @@ -65,13 +65,6 @@ android:persistent="false" android:title="@string/interaction_control_category_title"> - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/src/com/android/settings/accessibility/TapAssistanceFragment.java b/src/com/android/settings/accessibility/TapAssistanceFragment.java new file mode 100644 index 00000000000..1a999ea39a2 --- /dev/null +++ b/src/com/android/settings/accessibility/TapAssistanceFragment.java @@ -0,0 +1,50 @@ +/* + * 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.accessibility; + +import android.app.settings.SettingsEnums; + +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.search.SearchIndexable; + +/** Accessibility settings for tap assistance. */ +@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) +public class TapAssistanceFragment extends DashboardFragment { + + private static final String TAG = "TapAssistanceFragment"; + + @Override + public int getMetricsCategory() { + return SettingsEnums.ACCESSIBILITY_TAP_ASSISTANCE; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.accessibility_tap_assistance; + } + + @Override + protected String getLogTag() { + return TAG; + } + + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider(R.xml.accessibility_tap_assistance); + +} diff --git a/tests/robotests/src/com/android/settings/accessibility/TapAssistanceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/TapAssistanceFragmentTest.java new file mode 100644 index 00000000000..093ea0377f1 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/TapAssistanceFragmentTest.java @@ -0,0 +1,49 @@ +/* + * 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.accessibility; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; + +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.R; +import com.android.settings.testutils.XmlTestUtils; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +import java.util.List; + +@RunWith(RobolectricTestRunner.class) +/** Tests for {@link TapAssistanceFragment}. */ +public class TapAssistanceFragmentTest { + + private Context mContext = ApplicationProvider.getApplicationContext(); + + @Test + public void getNonIndexableKeys_existInXmlLayout() { + final List niks = TapAssistanceFragment.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + final List keys = + XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_tap_assistance); + + assertThat(keys).containsAtLeastElementsIn(niks); + } +} From 124f01999c7c8640786ceeee5967fc69fe0eed98 Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Thu, 7 Jan 2021 00:14:50 +0800 Subject: [PATCH 04/19] Set a title for personal dictionary After the collapsing toolbar layout is applied to subsetting pages, the title of the personal dictionary page won't be shown. This CL is to set a title for the personal dictionary page. Bug: 176897229 Test: manual test and visual verified 1) Navigate to Settings -> System -> Languages & input -> Personal dictionary 2) Enable collapsing toolbar feature 3) Observe and check if the title is shown as normal Change-Id: I0b6488bc2c8040b275ba0d5348d09aa4bad905d1 --- .../settings/inputmethod/UserDictionarySettings.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/com/android/settings/inputmethod/UserDictionarySettings.java b/src/com/android/settings/inputmethod/UserDictionarySettings.java index 67420a2c5df..5e3e7495359 100644 --- a/src/com/android/settings/inputmethod/UserDictionarySettings.java +++ b/src/com/android/settings/inputmethod/UserDictionarySettings.java @@ -26,6 +26,7 @@ import android.database.Cursor; import android.os.Bundle; import android.provider.UserDictionary; import android.text.TextUtils; +import android.util.FeatureFlagUtils; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -44,6 +45,7 @@ import androidx.loader.app.LoaderManager; import androidx.loader.content.Loader; import com.android.settings.R; +import com.android.settings.core.FeatureFlags; import com.android.settings.core.SubSettingLauncher; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.Instrumentable; @@ -104,6 +106,10 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // TODO(b/176883483): Remove the title after material component updated + if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.SILKY_HOME)) { + getActivity().setTitle(R.string.user_dict_settings_title); + } // Show the language as a subtitle of the action bar final ActionBar actionBar = getActivity().getActionBar(); if (actionBar != null) { From dda4c34d59bec458f48428e3785eab0582f7bd18 Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Wed, 6 Jan 2021 21:08:30 +0800 Subject: [PATCH 05/19] Update ScrollView to NestedScrollView in the font size page To ensure that the collapsing toolbar work as usual, we need to change the ScrollView to NestedScrollView. Bug: 176884647 Test: manual test and visual verified 1) Navigate to Settings -> Display -> Font size 2) Check if the sample text area is scrollable Change-Id: I1cb8a20f1efd69213e1eaadfe84a53aff9bc640f --- .../font_size_activity.xml | 4 +-- res/layout/font_size_activity.xml | 25 ++++++++++--------- res/layout/font_size_preview.xml | 5 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/res/layout-sw300dp-land/font_size_activity.xml b/res/layout-sw300dp-land/font_size_activity.xml index 666470424ae..7703eb2fc75 100644 --- a/res/layout-sw300dp-land/font_size_activity.xml +++ b/res/layout-sw300dp-land/font_size_activity.xml @@ -36,7 +36,7 @@ android:padding="6dp" /> - - + diff --git a/res/layout/font_size_activity.xml b/res/layout/font_size_activity.xml index 32de37d0f89..c3b26ae7526 100644 --- a/res/layout/font_size_activity.xml +++ b/res/layout/font_size_activity.xml @@ -14,17 +14,18 @@ limitations under the License. --> - + + android:layout_height="wrap_content"> - + + android:padding="6dp"/> + android:elevation="2dp"/> + android:contentDescription="@string/font_size_make_smaller_desc"/> + android:contentDescription="@string/font_size_make_larger_desc"/> + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"/> - + diff --git a/res/layout/font_size_preview.xml b/res/layout/font_size_preview.xml index 669ece05341..2b1773bcee3 100644 --- a/res/layout/font_size_preview.xml +++ b/res/layout/font_size_preview.xml @@ -14,7 +14,8 @@ limitations under the License. --> - @@ -57,4 +58,4 @@ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"/> - + From 14cfd2f2ca2049b8bdb9d0016986112958b93ab2 Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Wed, 6 Jan 2021 07:46:46 +0800 Subject: [PATCH 06/19] Add CollapsingToolbarLayout for sub settings Settings app is planning to make toolbar collapsible for next Android release. This CL is to add a new layout for CollapsingToolbarLayout in the Settings app and to update the theme correspondly. This feature will be controlled by feature flag, which makes Settings app compacitible with the existing layout. Bug: 174451673 Test: manul test and visual verification 1) Enable the feature and open Settings app 2) Navigate to each sub page and check if toolbar is collapsible Change-Id: Ibef524bbaa7ae3f0a43db7e40e599f42e009437f --- AndroidManifest.xml | 3 +- .../settings_collapsing_base_layout.xml | 64 +++++++++++++ res/values-night/themes.xml | 6 ++ res/values/styles.xml | 13 +++ res/values/themes.xml | 8 +- .../android/settings/SettingsActivity.java | 4 +- .../settings/SettingsPreferenceFragment.java | 9 +- .../settings/core/SettingsBaseActivity.java | 90 +++++++++++++++++-- 8 files changed, 187 insertions(+), 10 deletions(-) create mode 100644 res/layout/settings_collapsing_base_layout.xml diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c946122efc4..2eaebb1173a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -174,7 +174,8 @@ - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values-night/themes.xml b/res/values-night/themes.xml index c5f67febfa9..a4f495a6507 100644 --- a/res/values-night/themes.xml +++ b/res/values-night/themes.xml @@ -44,4 +44,10 @@ + + diff --git a/res/values/styles.xml b/res/values/styles.xml index ce6b09551a6..4ab1e6c90ec 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -874,4 +874,17 @@ 16sp ?android:attr/textColorSecondary + + + + + + diff --git a/res/values/themes.xml b/res/values/themes.xml index 01ea10302bf..fc692463dfa 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -72,7 +72,7 @@ true - + + diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 1c2952a3b46..7f214f67e23 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -288,7 +288,9 @@ public class SettingsActivity extends SettingsBaseActivity if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(!isInSetupWizard); actionBar.setHomeButtonEnabled(!isInSetupWizard); - actionBar.setDisplayShowTitleEnabled(true); + // TODO(b/176882938): Enable title after material component updated + // If CollapsingToolbarLayout is applied, the old action bar won't show title. + actionBar.setDisplayShowTitleEnabled(mCollapsingToolbarLayout == null); } mSwitchBar = findViewById(R.id.switch_bar); if (mSwitchBar != null) { diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index 659ada4bd40..2c628f6f375 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.FeatureFlagUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -42,6 +43,7 @@ import androidx.preference.PreferenceScreen; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.android.settings.core.FeatureFlags; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.search.actionbar.SearchMenuController; @@ -126,8 +128,11 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - SearchMenuController.init(this /* host */); - HelpMenuController.init(this /* host */); + // TODO(b/176883483): Remove both search and help menu if this feature rolled out + if (!FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.SILKY_HOME)) { + SearchMenuController.init(this /* host */); + HelpMenuController.init(this /* host */); + } if (icicle != null) { mPreferenceHighlighted = icicle.getBoolean(SAVE_HIGHLIGHTED_KEY); diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java index d160dc5e9d5..470470290d0 100644 --- a/src/com/android/settings/core/SettingsBaseActivity.java +++ b/src/com/android/settings/core/SettingsBaseActivity.java @@ -29,6 +29,7 @@ import android.os.AsyncTask; import android.os.Bundle; import android.text.TextUtils; import android.util.ArraySet; +import android.util.FeatureFlagUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -43,8 +44,11 @@ import com.android.settings.SubSettings; import com.android.settings.dashboard.CategoryManager; import com.android.settingslib.drawer.Tile; +import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.setupcompat.util.WizardManagerHelper; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -55,6 +59,7 @@ public class SettingsBaseActivity extends FragmentActivity { protected static final boolean DEBUG_TIMING = false; private static final String TAG = "SettingsBaseActivity"; private static final String DATA_SCHEME_PKG = "package"; + private static final int TOOLBAR_MAX_LINE_NUMBER = 2; // Serves as a temporary list of tiles to ignore until we heard back from the PM that they // are disabled. @@ -62,6 +67,8 @@ public class SettingsBaseActivity extends FragmentActivity { private final PackageReceiver mPackageReceiver = new PackageReceiver(); private final List mCategoryListeners = new ArrayList<>(); + + protected CollapsingToolbarLayout mCollapsingToolbarLayout; private int mCategoriesUpdateTaskCount; @Override @@ -79,21 +86,30 @@ public class SettingsBaseActivity extends FragmentActivity { requestWindowFeature(Window.FEATURE_NO_TITLE); } // Apply SetupWizard light theme during setup flow. This is for SubSettings pages. - if (WizardManagerHelper.isAnySetupWizard(getIntent()) && this instanceof SubSettings) { + final boolean isAnySetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent()); + if (isAnySetupWizard && this instanceof SubSettings) { setTheme(R.style.LightTheme_SubSettings_SetupWizard); } - super.setContentView(R.layout.settings_base_layout); + if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SILKY_HOME) + && isToolbarEnabled() && !isAnySetupWizard) { + super.setContentView(R.layout.settings_collapsing_base_layout); + mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar); + } else { + super.setContentView(R.layout.settings_base_layout); + } + + // This is to hide the toolbar from those pages which don't need a toolbar originally. final Toolbar toolbar = findViewById(R.id.action_bar); - if (theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) { + if (!isToolbarEnabled() || isAnySetupWizard) { toolbar.setVisibility(View.GONE); return; } setActionBar(toolbar); + initCollapsingToolbar(); if (DEBUG_TIMING) { - Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) - + " ms"); + Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) + " ms"); } } @@ -151,6 +167,70 @@ public class SettingsBaseActivity extends FragmentActivity { ((ViewGroup) findViewById(R.id.content_frame)).addView(view, params); } + @Override + public void setTitle(CharSequence title) { + if (mCollapsingToolbarLayout != null) { + mCollapsingToolbarLayout.setTitle(title); + } + super.setTitle(title); + } + + @Override + public void setTitle(int titleId) { + if (mCollapsingToolbarLayout != null) { + mCollapsingToolbarLayout.setTitle(getText(titleId)); + } + super.setTitle(titleId); + } + + /** + * SubSetting page should show a toolbar by default. If the page wouldn't show a toolbar, + * override this method and return false value. + * @return ture by default + */ + protected boolean isToolbarEnabled() { + return true; + } + + private void initCollapsingToolbar() { + if (mCollapsingToolbarLayout == null) { + return; + } + mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + v.removeOnLayoutChangeListener(this); + final int count = getLineCount(); + if (count > TOOLBAR_MAX_LINE_NUMBER) { + mCollapsingToolbarLayout + .setExpandedTitleTextAppearance(R.style.ToolbarText_MoreThanTwoLines); + } else { + mCollapsingToolbarLayout.setExpandedTitleTextAppearance(R.style.ToolbarText); + } + } + }); + } + + private int getLineCount() { + try { + final Class toolbarClazz = mCollapsingToolbarLayout.getClass(); + final Field textHelperField = toolbarClazz.getDeclaredField("collapsingTextHelper"); + textHelperField.setAccessible(true); + final Object textHelperObj = textHelperField.get(mCollapsingToolbarLayout); + + final Field layoutField = textHelperObj.getClass().getDeclaredField("textLayout"); + layoutField.setAccessible(true); + final Object layoutObj = layoutField.get(textHelperObj); + + final Method method = layoutObj.getClass().getDeclaredMethod("getLineCount"); + return (int) method.invoke(layoutObj); + } catch (Exception e) { + return 0; + } + } + + private void onCategoriesChanged(Set categories) { final int N = mCategoryListeners.size(); for (int i = 0; i < N; i++) { From 82df7e60a1fe82f6f9c8c8e38a36fac86ce1c3a7 Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Thu, 7 Jan 2021 00:49:14 +0800 Subject: [PATCH 07/19] Disable the title of mobile network After the collapsing toolbar layout is applied to subsetting pages, the mobile network page has two title shown currently. One is the activity title while the other is the collapsing toolbar title To make sure there will be only one title shown on this page, the activity title will be removed and we will keep the collapsing toolbar title. Bug: 176899590 Test: manual test and visual verified 1) Navigate to Settings -> Network & internet -> Mobile network 2) Check if there's only one title in this page Change-Id: I50e57468c640f1d176fd99dcaafc06ed3fc601dc --- .../settings/network/telephony/MobileNetworkActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java index b179770d485..92f0054d2e7 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java +++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java @@ -115,6 +115,9 @@ public class MobileNetworkActivity extends SettingsBaseActivity final ActionBar actionBar = getActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); + // TODO(b/176882938): Enable title after material component updated + // If CollapsingToolbarLayout is applied, the old action bar won't show title. + actionBar.setDisplayShowTitleEnabled(mCollapsingToolbarLayout == null); } getProxySubscriptionManager().setLifecycle(getLifecycle()); From 82777ba0c0b98cc0bfefb79e135be3edf769e442 Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Wed, 6 Jan 2021 20:48:57 +0800 Subject: [PATCH 08/19] Disable toolbar title of screen lock pages After applying collapsing toolbar in the Settings app, the toolbar title will be shown in every subsetting pages. However some pages in the security category don't need the title, like set screen lock page and lock screen page. This CL is to disable these titles through overriding isToolbarEnabled method. Bug: 176883575 Test: manual test and visual verified 1) Navigate to Settings -> Security -> Screen lock -> Pattern/PIN/Password 2) Observe and check if there is a duplicated title. Change-Id: I6dfa4fbe1b5e2ac3582804ba1e125196f3bdba6c --- .../android/settings/notification/RedactionInterstitial.java | 5 +++++ src/com/android/settings/password/ChooseLockPassword.java | 5 +++++ src/com/android/settings/password/ChooseLockPattern.java | 5 +++++ .../password/ConfirmDeviceCredentialBaseActivity.java | 5 +++++ .../android/settings/password/SetupChooseLockPassword.java | 4 +--- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/notification/RedactionInterstitial.java b/src/com/android/settings/notification/RedactionInterstitial.java index a17298f9d79..27e2b726c1f 100644 --- a/src/com/android/settings/notification/RedactionInterstitial.java +++ b/src/com/android/settings/notification/RedactionInterstitial.java @@ -77,6 +77,11 @@ public class RedactionInterstitial extends SettingsActivity { findViewById(R.id.content_parent).setFitsSystemWindows(false); } + @Override + protected boolean isToolbarEnabled() { + return false; + } + /** * Create an intent for launching RedactionInterstitial. * diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java index 0c84ba97628..f5e23fa04f2 100644 --- a/src/com/android/settings/password/ChooseLockPassword.java +++ b/src/com/android/settings/password/ChooseLockPassword.java @@ -184,6 +184,11 @@ public class ChooseLockPassword extends SettingsActivity { return false; } + @Override + protected boolean isToolbarEnabled() { + return false; + } + /* package */ Class getFragmentClass() { return ChooseLockPasswordFragment.class; } diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java index 6e9cf981509..c52b4104288 100644 --- a/src/com/android/settings/password/ChooseLockPattern.java +++ b/src/com/android/settings/password/ChooseLockPattern.java @@ -194,6 +194,11 @@ public class ChooseLockPattern extends SettingsActivity { return super.onKeyDown(keyCode, event); } + @Override + protected boolean isToolbarEnabled() { + return false; + } + public static class ChooseLockPatternFragment extends InstrumentedFragment implements SaveAndFinishWorker.Listener { diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java index 3ecff580d33..f0b50a1bfec 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java @@ -176,6 +176,11 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi } } + @Override + protected boolean isToolbarEnabled() { + return false; + } + public void prepareEnterAnimation() { getFragment().prepareEnterAnimation(); } diff --git a/src/com/android/settings/password/SetupChooseLockPassword.java b/src/com/android/settings/password/SetupChooseLockPassword.java index e82dc94e124..25f5a348904 100644 --- a/src/com/android/settings/password/SetupChooseLockPassword.java +++ b/src/com/android/settings/password/SetupChooseLockPassword.java @@ -24,7 +24,6 @@ import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; -import android.widget.LinearLayout; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -65,8 +64,7 @@ public class SetupChooseLockPassword extends ChooseLockPassword { @Override protected void onCreate(Bundle savedInstance) { super.onCreate(savedInstance); - LinearLayout layout = (LinearLayout) findViewById(R.id.content_parent); - layout.setFitsSystemWindows(false); + findViewById(R.id.content_parent).setFitsSystemWindows(false); } public static class SetupChooseLockPasswordFragment extends ChooseLockPasswordFragment From b9e320c8e70b6a7fdb5ddef0d7ba8e769cced1c5 Mon Sep 17 00:00:00 2001 From: joshmccloskey Date: Fri, 8 Jan 2021 11:30:27 -0800 Subject: [PATCH 09/19] Add immutability flag to face slice Fix: 172212761 Test: Verified suggestion icon appears. Change-Id: Ia17ca67d7d729e0608169c23f9df0c1a9d473c85 --- .../homepage/contextualcards/slices/FaceSetupSlice.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSlice.java b/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSlice.java index 0ad241e7431..1b3ee10b233 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSlice.java +++ b/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSlice.java @@ -143,8 +143,8 @@ public class FaceSetupSlice implements CustomSliceable { private static RowBuilder buildRowBuilder(CharSequence title, CharSequence subTitle, IconCompat icon, Context context, Intent intent) { final SliceAction primarySliceAction = SliceAction.createDeeplink( - PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_MUTABLE_UNAUDITED), icon, ListBuilder.ICON_IMAGE, - title); + PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE), + icon, ListBuilder.ICON_IMAGE, title); return new RowBuilder() .setTitleItem(icon, ListBuilder.ICON_IMAGE) .setTitle(title) From 1b372913649eefd8764cf94ebd41f373a291ea29 Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Wed, 6 Jan 2021 23:48:28 +0800 Subject: [PATCH 10/19] Change ScrollView to NestedScrollView for screen size page To make sure the collapsing toolbar work as usual, we need to use NestedScrollView instead of ScrollView in the screen size page. Bug: 176896338 Test: manual test and visual verified 1) Navigate to Settings -> Display -> Display size 2) Change the size on the seekbar 3) Observe and check if the preview window can be scrolled Change-Id: Ia5bb66ef63b9d9a7713cebddbf6ab6258ff82b8d --- .../screen_zoom_activity.xml | 4 +-- res/layout/preview_seek_bar_view_pager.xml | 2 +- res/layout/screen_zoom_activity.xml | 25 ++++++++++--------- res/layout/screen_zoom_preview_1.xml | 5 ++-- res/layout/screen_zoom_preview_settings.xml | 5 ++-- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/res/layout-sw300dp-land/screen_zoom_activity.xml b/res/layout-sw300dp-land/screen_zoom_activity.xml index 0f1c000b000..1cdb5b439c6 100644 --- a/res/layout-sw300dp-land/screen_zoom_activity.xml +++ b/res/layout-sw300dp-land/screen_zoom_activity.xml @@ -38,7 +38,7 @@ android:padding="6dp" /> - - + diff --git a/res/layout/preview_seek_bar_view_pager.xml b/res/layout/preview_seek_bar_view_pager.xml index 12f26110b36..6ddff130451 100644 --- a/res/layout/preview_seek_bar_view_pager.xml +++ b/res/layout/preview_seek_bar_view_pager.xml @@ -25,7 +25,7 @@ diff --git a/res/layout/screen_zoom_activity.xml b/res/layout/screen_zoom_activity.xml index 4cfa7b6ae98..00831fbe55f 100644 --- a/res/layout/screen_zoom_activity.xml +++ b/res/layout/screen_zoom_activity.xml @@ -14,17 +14,18 @@ limitations under the License. --> - + + android:layout_height="wrap_content"> - + + android:padding="6dp"/> + android:elevation="2dp"/> + android:contentDescription="@string/screen_zoom_make_smaller_desc"/> + android:contentDescription="@string/screen_zoom_make_larger_desc"/> + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"/> - + diff --git a/res/layout/screen_zoom_preview_1.xml b/res/layout/screen_zoom_preview_1.xml index 65d27ee6896..9290df95e4b 100644 --- a/res/layout/screen_zoom_preview_1.xml +++ b/res/layout/screen_zoom_preview_1.xml @@ -13,7 +13,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - - + diff --git a/res/layout/screen_zoom_preview_settings.xml b/res/layout/screen_zoom_preview_settings.xml index 3401fcf1971..de163928a8b 100644 --- a/res/layout/screen_zoom_preview_settings.xml +++ b/res/layout/screen_zoom_preview_settings.xml @@ -14,7 +14,8 @@ limitations under the License. --> - - + From 3440b9529f6f5e0610c15f4f1ee462b1604ff098 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Mon, 11 Jan 2021 15:25:02 -0800 Subject: [PATCH 11/19] Remove some emergency setting items scattered in settings All these items are displayed in the new Safety & emergency page. Bug: 175158310 Test: manual Change-Id: I3e323f2452db6d62aa98c79835c964c1c06a06cf --- res/xml/gestures.xml | 6 ------ res/xml/my_device_info.xml | 7 ------- res/xml/top_level_settings.xml | 13 ++++++------- res/xml/top_level_settings_grouped.xml | 15 ++++++++------- 4 files changed, 14 insertions(+), 27 deletions(-) diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml index 32dad203e43..970ad217bfd 100644 --- a/res/xml/gestures.xml +++ b/res/xml/gestures.xml @@ -20,12 +20,6 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/gesture_preference_title"> - - - - - - - - - - - + - - - - - - - + + + Date: Mon, 11 Jan 2021 22:57:45 +0800 Subject: [PATCH 12/19] Refine the preference layout for homepage Based on the Android S design, we update the layout for homepage. The scope covers the layout of preference and icons itself. - Change the icon size for IA items. - Change the layout spacing of preference. - Change the margin or search bar. Test: See the screen and confirm with UX Bug: 177213699 Change-Id: I985966fdf39a5989d51991aa3c06ea5fd31e8fe2 --- color-check-baseline.xml | 396 ++++++++++++++++-- res/drawable/ic_homepage_about_v2.xml | 33 ++ res/drawable/ic_homepage_accessibility_v2.xml | 33 ++ res/drawable/ic_homepage_accounts_v2.xml | 33 ++ res/drawable/ic_homepage_apps_v2.xml | 33 ++ res/drawable/ic_homepage_battery_v2.xml | 33 ++ .../ic_homepage_connected_device_v2.xml | 33 ++ res/drawable/ic_homepage_display_v2.xml | 33 ++ res/drawable/ic_homepage_emergency_v2.xml | 33 ++ res/drawable/ic_homepage_location_v2.xml | 33 ++ res/drawable/ic_homepage_network_v2.xml | 33 ++ res/drawable/ic_homepage_notification_v2.xml | 33 ++ res/drawable/ic_homepage_privacy_v2.xml | 33 ++ res/drawable/ic_homepage_security_v2.xml | 33 ++ res/drawable/ic_homepage_sound_v2.xml | 33 ++ res/drawable/ic_homepage_storage_v2.xml | 33 ++ res/drawable/ic_homepage_support_v2.xml | 33 ++ .../ic_homepage_system_dashboard_v2.xml | 33 ++ res/drawable/ic_homepage_wallpaper_v2.xml | 33 ++ res/layout/homepage_preference.xml | 65 +++ res/layout/search_bar.xml | 5 +- res/values/dimens.xml | 6 + res/values/styles.xml | 6 + res/xml/top_level_settings_grouped.xml | 73 ++-- ...TopLevelWallpaperPreferenceController.java | 23 +- .../settings/homepage/HomePagePreference.java | 49 +++ .../RestrictedHomepagePreference.java | 122 ++++++ 27 files changed, 1268 insertions(+), 71 deletions(-) create mode 100644 res/drawable/ic_homepage_about_v2.xml create mode 100644 res/drawable/ic_homepage_accessibility_v2.xml create mode 100644 res/drawable/ic_homepage_accounts_v2.xml create mode 100644 res/drawable/ic_homepage_apps_v2.xml create mode 100644 res/drawable/ic_homepage_battery_v2.xml create mode 100644 res/drawable/ic_homepage_connected_device_v2.xml create mode 100644 res/drawable/ic_homepage_display_v2.xml create mode 100644 res/drawable/ic_homepage_emergency_v2.xml create mode 100644 res/drawable/ic_homepage_location_v2.xml create mode 100644 res/drawable/ic_homepage_network_v2.xml create mode 100644 res/drawable/ic_homepage_notification_v2.xml create mode 100644 res/drawable/ic_homepage_privacy_v2.xml create mode 100644 res/drawable/ic_homepage_security_v2.xml create mode 100644 res/drawable/ic_homepage_sound_v2.xml create mode 100644 res/drawable/ic_homepage_storage_v2.xml create mode 100644 res/drawable/ic_homepage_support_v2.xml create mode 100644 res/drawable/ic_homepage_system_dashboard_v2.xml create mode 100644 res/drawable/ic_homepage_wallpaper_v2.xml create mode 100644 res/layout/homepage_preference.xml create mode 100644 src/com/android/settings/homepage/HomePagePreference.java create mode 100644 src/com/android/settings/homepage/RestrictedHomepagePreference.java diff --git a/color-check-baseline.xml b/color-check-baseline.xml index 768929b6b98..eac6d3c2511 100644 --- a/color-check-baseline.xml +++ b/color-check-baseline.xml @@ -1,6 +1,18 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2973,7 +3305,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2989,7 +3321,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3005,7 +3337,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3021,7 +3353,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3037,7 +3369,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3053,7 +3385,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3069,7 +3401,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3121,6 +3453,22 @@ column="9"/> + + + + @@ -3149,7 +3497,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> @@ -3165,7 +3513,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> @@ -3181,26 +3529,10 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> - - - - @@ -3261,7 +3593,7 @@ errorLine2=" ^"> @@ -3277,7 +3609,7 @@ errorLine2=" ^"> @@ -3293,7 +3625,7 @@ errorLine2=" ^"> diff --git a/res/drawable/ic_homepage_about_v2.xml b/res/drawable/ic_homepage_about_v2.xml new file mode 100644 index 00000000000..c069bfc98ba --- /dev/null +++ b/res/drawable/ic_homepage_about_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_accessibility_v2.xml b/res/drawable/ic_homepage_accessibility_v2.xml new file mode 100644 index 00000000000..24ca8cf20f9 --- /dev/null +++ b/res/drawable/ic_homepage_accessibility_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_accounts_v2.xml b/res/drawable/ic_homepage_accounts_v2.xml new file mode 100644 index 00000000000..6ea981ff206 --- /dev/null +++ b/res/drawable/ic_homepage_accounts_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_apps_v2.xml b/res/drawable/ic_homepage_apps_v2.xml new file mode 100644 index 00000000000..c6ac0c4f6da --- /dev/null +++ b/res/drawable/ic_homepage_apps_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_battery_v2.xml b/res/drawable/ic_homepage_battery_v2.xml new file mode 100644 index 00000000000..680031fe592 --- /dev/null +++ b/res/drawable/ic_homepage_battery_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_connected_device_v2.xml b/res/drawable/ic_homepage_connected_device_v2.xml new file mode 100644 index 00000000000..f3e95d23f91 --- /dev/null +++ b/res/drawable/ic_homepage_connected_device_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_display_v2.xml b/res/drawable/ic_homepage_display_v2.xml new file mode 100644 index 00000000000..e4014ee4daa --- /dev/null +++ b/res/drawable/ic_homepage_display_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_emergency_v2.xml b/res/drawable/ic_homepage_emergency_v2.xml new file mode 100644 index 00000000000..86d1470f5ea --- /dev/null +++ b/res/drawable/ic_homepage_emergency_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_location_v2.xml b/res/drawable/ic_homepage_location_v2.xml new file mode 100644 index 00000000000..5dc72eb1855 --- /dev/null +++ b/res/drawable/ic_homepage_location_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_network_v2.xml b/res/drawable/ic_homepage_network_v2.xml new file mode 100644 index 00000000000..d3b33e96fe2 --- /dev/null +++ b/res/drawable/ic_homepage_network_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_notification_v2.xml b/res/drawable/ic_homepage_notification_v2.xml new file mode 100644 index 00000000000..9b57456f277 --- /dev/null +++ b/res/drawable/ic_homepage_notification_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_privacy_v2.xml b/res/drawable/ic_homepage_privacy_v2.xml new file mode 100644 index 00000000000..56e6da82ce8 --- /dev/null +++ b/res/drawable/ic_homepage_privacy_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_security_v2.xml b/res/drawable/ic_homepage_security_v2.xml new file mode 100644 index 00000000000..5e33add6613 --- /dev/null +++ b/res/drawable/ic_homepage_security_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_sound_v2.xml b/res/drawable/ic_homepage_sound_v2.xml new file mode 100644 index 00000000000..8561820e549 --- /dev/null +++ b/res/drawable/ic_homepage_sound_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_storage_v2.xml b/res/drawable/ic_homepage_storage_v2.xml new file mode 100644 index 00000000000..1a8b7d28b4e --- /dev/null +++ b/res/drawable/ic_homepage_storage_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_support_v2.xml b/res/drawable/ic_homepage_support_v2.xml new file mode 100644 index 00000000000..81399738279 --- /dev/null +++ b/res/drawable/ic_homepage_support_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_system_dashboard_v2.xml b/res/drawable/ic_homepage_system_dashboard_v2.xml new file mode 100644 index 00000000000..7c016a2080f --- /dev/null +++ b/res/drawable/ic_homepage_system_dashboard_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_wallpaper_v2.xml b/res/drawable/ic_homepage_wallpaper_v2.xml new file mode 100644 index 00000000000..ee16339ac95 --- /dev/null +++ b/res/drawable/ic_homepage_wallpaper_v2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/layout/homepage_preference.xml b/res/layout/homepage_preference.xml new file mode 100644 index 00000000000..c08a74f2418 --- /dev/null +++ b/res/layout/homepage_preference.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/search_bar.xml b/res/layout/search_bar.xml index d3e98c37ea3..c4dd15dc243 100644 --- a/res/layout/search_bar.xml +++ b/res/layout/search_bar.xml @@ -20,7 +20,10 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="@dimen/search_bar_margin" + android:layout_marginTop="@dimen/search_bar_margin" + android:layout_marginStart="@dimen/search_bar_margin" + android:layout_marginEnd="@dimen/search_bar_margin" + android:layout_marginBottom="16dp" app:layout_scrollFlags="scroll|enterAlways"> 6dp + + 48dp + + + 12dp + 12dp diff --git a/res/values/styles.xml b/res/values/styles.xml index 4ab1e6c90ec..e75766d36e2 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -312,6 +312,12 @@ @dimen/search_bar_text_size + +