From 8e5807fcc90986aeeacb417a41fb28e2f2821a2c Mon Sep 17 00:00:00 2001 From: Sunny Shao Date: Fri, 16 Nov 2018 15:44:53 +0800 Subject: [PATCH 01/13] Refined the CardContentProvider unused operations updated delete and update operations to throw UnsupportedOperationException Bug: 119647595 Test: robotest Change-Id: If77662213b89dc91b9ca2d6b028c635a46266eab --- .../contextualcards/CardContentProvider.java | 25 +------- .../CardContentProviderTest.java | 61 +------------------ 2 files changed, 4 insertions(+), 82 deletions(-) diff --git a/src/com/android/settings/homepage/contextualcards/CardContentProvider.java b/src/com/android/settings/homepage/contextualcards/CardContentProvider.java index 74e09e8d467..808814352b9 100644 --- a/src/com/android/settings/homepage/contextualcards/CardContentProvider.java +++ b/src/com/android/settings/homepage/contextualcards/CardContentProvider.java @@ -98,17 +98,7 @@ public class CardContentProvider extends ContentProvider { @Override public int delete(Uri uri, String selection, String[] selectionArgs) { - final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy(); - try { - maybeEnableStrictMode(); - final SQLiteDatabase database = mDBHelper.getWritableDatabase(); - final String table = getTableFromMatch(uri); - final int rowsDeleted = database.delete(table, selection, selectionArgs); - getContext().getContentResolver().notifyChange(uri, null /* observer */); - return rowsDeleted; - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } + throw new UnsupportedOperationException("delete operation not supported currently."); } @Override @@ -140,18 +130,7 @@ public class CardContentProvider extends ContentProvider { @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy(); - try { - maybeEnableStrictMode(); - - final SQLiteDatabase database = mDBHelper.getWritableDatabase(); - final String table = getTableFromMatch(uri); - final int rowsUpdated = database.update(table, values, selection, selectionArgs); - getContext().getContentResolver().notifyChange(uri, null /* observer */); - return rowsUpdated; - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } + throw new UnsupportedOperationException("update operation not supported currently."); } @VisibleForTesting diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/CardContentProviderTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/CardContentProviderTest.java index 0ffabb47085..1e444bb2e4f 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/CardContentProviderTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/CardContentProviderTest.java @@ -95,15 +95,12 @@ public class CardContentProviderTest { assertThat(count).isGreaterThan(0); } - @Test + @Test(expected = UnsupportedOperationException.class) public void cardData_delete() { - mResolver.insert(mUri, generateOneRow()); final int delCount = mResolver.delete(mUri, null, null); - - assertThat(delCount).isGreaterThan(0); } - @Test + @Test(expected = UnsupportedOperationException.class) public void cardData_update() { mResolver.insert(mUri, generateOneRow()); @@ -113,16 +110,6 @@ public class CardContentProviderTest { final String strWhere = CardDatabaseHelper.CardColumns.NAME + "=?"; final String[] selectionArgs = {"auto_rotate"}; final int updateCount = mResolver.update(mUri, values, strWhere, selectionArgs); - - assertThat(updateCount).isGreaterThan(0); - - final String[] columns = {CardDatabaseHelper.CardColumns.SCORE}; - final Cursor cr = mResolver.query(mUri, columns, strWhere, selectionArgs, null); - cr.moveToFirst(); - final double qryScore = cr.getDouble(0); - - cr.close(); - assertThat(qryScore).isEqualTo(updatingScore); } @Test @@ -145,28 +132,6 @@ public class CardContentProviderTest { verify(mProvider).enableStrictMode(); } - @Test - public void delete_isMainThread_shouldEnableStrictMode() { - ShadowThreadUtils.setIsMainThread(true); - ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true); - - mProvider.delete(mUri, null, null); - - verify(mProvider).enableStrictMode(); - } - - @Test - public void update_isMainThread_shouldEnableStrictMode() { - ShadowThreadUtils.setIsMainThread(true); - ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true); - final ContentValues values = new ContentValues(); - values.put(CardDatabaseHelper.CardColumns.SCORE, "0.01"); - - mProvider.update(mUri, values, null, null); - - verify(mProvider).enableStrictMode(); - } - @Test public void insert_notMainThread_shouldNotEnableStrictMode() { ShadowThreadUtils.setIsMainThread(false); @@ -187,28 +152,6 @@ public class CardContentProviderTest { verify(mProvider, never()).enableStrictMode(); } - @Test - public void delete_notMainThread_shouldNotEnableStrictMode() { - ShadowThreadUtils.setIsMainThread(false); - ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true); - - mProvider.delete(mUri, null, null); - - verify(mProvider, never()).enableStrictMode(); - } - - @Test - public void update_notMainThread_shouldNotEnableStrictMode() { - ShadowThreadUtils.setIsMainThread(false); - ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true); - final ContentValues values = new ContentValues(); - values.put(CardDatabaseHelper.CardColumns.SCORE, "0.01"); - - mProvider.update(mUri, values, null, null); - - verify(mProvider, never()).enableStrictMode(); - } - @Test(expected = UnsupportedOperationException.class) public void getType_shouldCrash() { mProvider.getType(null); From ac00f2cb763e098d4fad140ac053228c9b28a06f Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Fri, 16 Nov 2018 13:06:37 -0800 Subject: [PATCH 02/13] Fix data usage failing test. - update the tests that faile when data usage v2 is turned on. Change-Id: I6bd09245d695791fb1564b6e598600e889d0712f Fixes: 117433810 Test: make RunSettingsRoboTests --- .../appinfo/AppDataUsagePreferenceControllerTest.java | 4 ++++ .../com/android/settings/datausage/DataUsageSummaryTest.java | 4 ++++ .../network/telephony/DataUsagePreferenceControllerTest.java | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java index e77106d2a01..1adc6781aec 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java @@ -16,6 +16,8 @@ package com.android.settings.applications.appinfo; +import static com.android.settings.core.FeatureFlags.DATA_USAGE_V2; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -33,6 +35,7 @@ import android.content.pm.ApplicationInfo; import android.net.ConnectivityManager; import android.net.INetworkStatsSession; import android.os.Bundle; +import android.util.FeatureFlagUtils; import androidx.loader.app.LoaderManager; import androidx.preference.Preference; @@ -65,6 +68,7 @@ public class AppDataUsagePreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application.getApplicationContext()); + FeatureFlagUtils.setEnabled(mContext, DATA_USAGE_V2, false); mController = spy(new AppDataUsagePreferenceController(mContext, "test_key")); mController.setParentFragment(mFragment); } diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java index 49e3e864c9f..9fee9f0ffa2 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import android.app.usage.NetworkStatsManager; import android.content.Context; import android.net.NetworkPolicyManager; @@ -68,6 +69,8 @@ public class DataUsageSummaryTest { private SummaryLoader mSummaryLoader; @Mock private NetworkPolicyManager mNetworkPolicyManager; + @Mock + private NetworkStatsManager mNetworkStatsManager; private Context mContext; private FragmentActivity mActivity; private SummaryLoader.SummaryProvider mSummaryProvider; @@ -86,6 +89,7 @@ public class DataUsageSummaryTest { mContext = RuntimeEnvironment.application; mActivity = spy(Robolectric.buildActivity(FragmentActivity.class).get()); + doReturn(mNetworkStatsManager).when(mActivity).getSystemService(NetworkStatsManager.class); mSummaryProvider = DataUsageSummary.SUMMARY_PROVIDER_FACTORY .createSummaryProvider(mActivity, mSummaryLoader); diff --git a/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java index ea6f903cecc..1d91bb875ba 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.Activity; +import android.app.usage.NetworkStatsManager; import android.content.Context; import android.content.Intent; import android.provider.Settings; @@ -48,6 +49,8 @@ public class DataUsagePreferenceControllerTest { @Mock private TelephonyManager mTelephonyManager; + @Mock + private NetworkStatsManager mNetworkStatsManager; private DataUsagePreferenceController mController; private SwitchPreference mPreference; private Context mContext; @@ -59,6 +62,7 @@ public class DataUsagePreferenceControllerTest { mContext = spy(Robolectric.setupActivity(Activity.class)); doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE); doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID); + doReturn(mNetworkStatsManager).when(mContext).getSystemService(NetworkStatsManager.class); mPreference = new SwitchPreference(mContext); mController = new DataUsagePreferenceController(mContext, "data_usage"); From 9f1c6170166d67fd71020953be94005798995102 Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Wed, 10 Oct 2018 17:06:15 -0700 Subject: [PATCH 03/13] Disable toggling wifi tethering in secondary user. - in previous release, the shortcut widget was for the top level Hotspot & Tethering settings page. The top level settings has logic to check whether the page is restricted and remove all preferences and show a message to tell the user that tethering settings are not available, and the user will not be able to launch the wifi hotspot settings page. - the updated shortcut now launches the wifi hotspot page directly. The settings does not check for restriction. Copy the logic from the top level settings to check for restriction and remove all preferences accordingly. Change-Id: I76fb7838e2db379f6ffbce7bf14003bccc1b10d3 Fixes: 116642428 Test: make RunSettingsRoboTests --- .../wifi/tether/WifiTetherSettings.java | 23 +++++++++++ .../wifi/tether/WifiTetherSettingsTest.java | 38 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java index 647ba5a838b..c98fbdbdc3e 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java +++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java @@ -71,6 +71,7 @@ public class WifiTetherSettings extends RestrictedDashboardFragment private WifiManager mWifiManager; private boolean mRestartWifiApAfterConfigChange; + private boolean mUnavailable; @VisibleForTesting TetherChangeReceiver mTetherChangeReceiver; @@ -94,6 +95,15 @@ public class WifiTetherSettings extends RestrictedDashboardFragment return "WifiTetherSettings"; } + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + setIfOnlyAvailableForAdmins(true); + if (isUiRestricted()) { + mUnavailable = true; + } + } + @Override public void onAttach(Context context) { super.onAttach(context); @@ -109,6 +119,9 @@ public class WifiTetherSettings extends RestrictedDashboardFragment @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); + if (mUnavailable) { + return; + } // Assume we are in a SettingsActivity. This is only safe because we currently use // SettingsActivity as base for all preference fragments. final SettingsActivity activity = (SettingsActivity) getActivity(); @@ -122,6 +135,13 @@ public class WifiTetherSettings extends RestrictedDashboardFragment @Override public void onStart() { super.onStart(); + if (mUnavailable) { + if (!isUiRestrictedByOnlyAdmin()) { + getEmptyTextView().setText(R.string.tethering_settings_not_available); + } + getPreferenceScreen().removeAll(); + return; + } final Context context = getContext(); if (context != null) { context.registerReceiver(mTetherChangeReceiver, TETHER_STATE_CHANGE_FILTER); @@ -131,6 +151,9 @@ public class WifiTetherSettings extends RestrictedDashboardFragment @Override public void onStop() { super.onStop(); + if (mUnavailable) { + return; + } final Context context = getContext(); if (context != null) { context.unregisterReceiver(mTetherChangeReceiver); diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java index 4b765e845ed..ef1a3b68854 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java @@ -18,15 +18,24 @@ package com.android.settings.wifi.tether; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.nullable; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.content.res.Resources; import android.net.ConnectivityManager; +import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; +import android.widget.TextView; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowWifiManager; @@ -37,10 +46,14 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; +import androidx.fragment.app.FragmentActivity; +import androidx.preference.PreferenceScreen; + @RunWith(SettingsRobolectricTestRunner.class) @Config(shadows = {ShadowWifiManager.class}) public class WifiTetherSettingsTest { @@ -98,6 +111,31 @@ public class WifiTetherSettingsTest { .isNotEmpty(); } + @Test + public void startFragment_notAdminUser_shouldRemoveAllPreferences() { + final WifiTetherSettings settings = spy(new WifiTetherSettings()); + final FragmentActivity activity = mock(FragmentActivity.class); + when(settings.getActivity()).thenReturn(activity); + when(settings.getContext()).thenReturn(mContext); + final Resources.Theme theme = mContext.getTheme(); + when(activity.getTheme()).thenReturn(theme); + when(activity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); + doNothing().when(settings) + .onCreatePreferences(any(Bundle.class), nullable(String.class)); + final FakeFeatureFactory fakeFeatureFactory = FakeFeatureFactory.setupForTest(); + ReflectionHelpers.setField(settings, "mDashboardFeatureProvider", + fakeFeatureFactory.dashboardFeatureProvider); + final TextView emptyTextView = mock(TextView.class); + ReflectionHelpers.setField(settings, "mEmptyTextView", emptyTextView); + final PreferenceScreen screen = mock(PreferenceScreen.class); + doReturn(screen).when(settings).getPreferenceScreen(); + settings.onCreate(Bundle.EMPTY); + + settings.onStart(); + + verify(screen).removeAll(); + } + private void setupIsTetherAvailable(boolean returnValue) { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); From 787cfb34c8c296c83ee769b52ded4e1eda9cfa02 Mon Sep 17 00:00:00 2001 From: tmfang Date: Mon, 19 Nov 2018 13:45:16 +0800 Subject: [PATCH 04/13] Apply new action buttons style for instant app Test: visual Bug: 116346008 Change-Id: I5a9f31960da28757e51683db4011820f7339e2f9 --- res/layout/instant_app_buttons.xml | 48 ++++++++++++++++-------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/res/layout/instant_app_buttons.xml b/res/layout/instant_app_buttons.xml index f80ac104fff..24b08bb2615 100644 --- a/res/layout/instant_app_buttons.xml +++ b/res/layout/instant_app_buttons.xml @@ -20,44 +20,48 @@ android:id="@+id/instant_app_button_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:gravity="center" - android:paddingTop="24dp" - android:paddingStart="68dp" - android:paddingEnd="24dp" - android:orientation="horizontal"> + android:paddingStart="8dp" + android:paddingEnd="8dp"> +