From e98c54dd6922a779d1e8bf3781503ee1d9d807a7 Mon Sep 17 00:00:00 2001 From: Mike Ma Date: Thu, 4 Jan 2018 18:35:03 -0800 Subject: [PATCH 01/30] Fix FakeUid implementation Test: local build Change-Id: Ia1d7ac98e9f1abd12e483b101b45fefab34eb235 --- src/com/android/settings/fuelgauge/FakeUid.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/com/android/settings/fuelgauge/FakeUid.java b/src/com/android/settings/fuelgauge/FakeUid.java index cbd9c3fa267..063185e3bdd 100644 --- a/src/com/android/settings/fuelgauge/FakeUid.java +++ b/src/com/android/settings/fuelgauge/FakeUid.java @@ -362,6 +362,16 @@ public class FakeUid extends Uid { return null; } + @Override + public long getCpuActiveTime() { + return 0; + } + + @Override + public long[] getCpuClusterTimes() { + return null; + } + @Override public long[] getCpuFreqTimes(int procState, int which) { return null; From 82254b08fd4d74c6a707fe20cec8c68a3e54b329 Mon Sep 17 00:00:00 2001 From: Matthew Fritze Date: Wed, 10 Jan 2018 10:13:00 -0800 Subject: [PATCH 02/30] Add dynamic summaries to Slices Summary on slices will now determined by checking that summaries in the following order are valid: 1) SliceData summary 2) Preference Controller summary 3) SliceData screen title Valid is currently defined as: - Not empty / null - Not whitespace - Not sumamry placeholder Fixes: 71640678 Test: robotests Change-Id: I5e699e8566ece80742d311617b7dc4e9a9bda8cf --- .../slices/SliceBroadcastReceiver.java | 8 +-- .../settings/slices/SliceBuilderUtils.java | 48 ++++++++++--- .../settings/slices/SliceDataConverter.java | 2 +- ...lsTest.java => SliceBuilderUtilsTest.java} | 69 +++++++++++++++++-- 4 files changed, 109 insertions(+), 18 deletions(-) rename tests/robotests/src/com/android/settings/slices/{SlicesDatabaseUtilsTest.java => SliceBuilderUtilsTest.java} (51%) diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java index 970b72a9caf..a68ed19db1d 100644 --- a/src/com/android/settings/slices/SliceBroadcastReceiver.java +++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java @@ -71,7 +71,7 @@ public class SliceBroadcastReceiver extends BroadcastReceiver { throw new IllegalStateException("No key passed to Intent for toggle controller"); } - BasePreferenceController controller = getBasePreferenceController(context, key); + final BasePreferenceController controller = getPreferenceController(context, key); if (!(controller instanceof TogglePreferenceController)) { throw new IllegalStateException("Toggle action passed for a non-toggle key: " + key); @@ -79,12 +79,12 @@ public class SliceBroadcastReceiver extends BroadcastReceiver { // TODO post context.getContentResolver().notifyChanged(uri, null) in the Toggle controller // so that it's automatically broadcast to any slice. - TogglePreferenceController toggleController = (TogglePreferenceController) controller; - boolean currentValue = toggleController.isChecked(); + final TogglePreferenceController toggleController = (TogglePreferenceController) controller; + final boolean currentValue = toggleController.isChecked(); toggleController.setChecked(!currentValue); } - private BasePreferenceController getBasePreferenceController(Context context, String key) { + private BasePreferenceController getPreferenceController(Context context, String key) { final SlicesDatabaseAccessor accessor = new SlicesDatabaseAccessor(context); final SliceData sliceData = accessor.getSliceDataFromKey(key); return SliceBuilderUtils.getPreferenceController(context, sliceData); diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java index 014ead28c22..e9152bab74a 100644 --- a/src/com/android/settings/slices/SliceBuilderUtils.java +++ b/src/com/android/settings/slices/SliceBuilderUtils.java @@ -24,10 +24,13 @@ import android.content.Intent; import android.graphics.drawable.Icon; import android.text.TextUtils; +import com.android.internal.annotations.VisibleForTesting; +import com.android.settings.R; import com.android.settings.SubSettings; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.TogglePreferenceController; import com.android.settings.search.DatabaseIndexingUtils; +import com.android.settingslib.core.AbstractPreferenceController; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -54,21 +57,17 @@ public class SliceBuilderUtils { public static Slice buildSlice(Context context, SliceData sliceData) { final PendingIntent contentIntent = getContentIntent(context, sliceData); final Icon icon = Icon.createWithResource(context, sliceData.getIconResource()); - String summaryText = sliceData.getSummary(); - String subtitleText = TextUtils.isEmpty(summaryText) - ? sliceData.getScreenTitle() - : summaryText; + final BasePreferenceController controller = getPreferenceController(context, sliceData); - RowBuilder builder = new RowBuilder(context, sliceData.getUri()) + final String subtitleText = getSubtitleText(context, controller, sliceData); + + final RowBuilder builder = new RowBuilder(context, sliceData.getUri()) .setTitle(sliceData.getTitle()) .setTitleItem(icon) .setSubtitle(subtitleText) .setContentIntent(contentIntent); - BasePreferenceController controller = getPreferenceController(context, sliceData); - // TODO (b/71640747) Respect setting availability. - // TODO (b/71640678) Add dynamic summary text. if (controller instanceof TogglePreferenceController) { addToggleAction(context, builder, ((TogglePreferenceController) controller).isChecked(), @@ -82,7 +81,7 @@ public class SliceBuilderUtils { /** * Looks at the {@link SliceData#preferenceController} from {@param sliceData} and attempts to - * build a {@link BasePreferenceController}. + * build an {@link AbstractPreferenceController}. */ public static BasePreferenceController getPreferenceController(Context context, SliceData sliceData) { @@ -122,4 +121,35 @@ public class SliceBuilderUtils { intent.setClassName("com.android.settings", SubSettings.class.getName()); return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */); } + + @VisibleForTesting + static String getSubtitleText(Context context, AbstractPreferenceController controller, + SliceData sliceData) { + String summaryText = sliceData.getSummary(); + if (isValidSummary(context, summaryText)) { + return summaryText; + } + + if (controller != null) { + summaryText = controller.getSummary(); + + if (isValidSummary(context, summaryText)) { + return summaryText; + } + } + + return sliceData.getScreenTitle(); + } + + private static boolean isValidSummary(Context context, String summary) { + if (summary == null || TextUtils.isEmpty(summary.trim())) { + return false; + } + + final String placeHolder = context.getString(R.string.summary_placeholder); + final String doublePlaceHolder = context.getString(R.string.summary_two_lines_placeholder); + + return !(TextUtils.equals(summary, placeHolder) + || TextUtils.equals(summary, doublePlaceHolder)); + } } diff --git a/src/com/android/settings/slices/SliceDataConverter.java b/src/com/android/settings/slices/SliceDataConverter.java index 4d9b7a5ed6c..c10753f5a73 100644 --- a/src/com/android/settings/slices/SliceDataConverter.java +++ b/src/com/android/settings/slices/SliceDataConverter.java @@ -163,7 +163,7 @@ class SliceDataConverter { // TODO (b/67996923) Non-controller Slices should become intent-only slices. // Note that without a controller, dynamic summaries are impossible. - // TODO (b/67996923) This will not work if preferences have nested intens: + // TODO (b/67996923) This will not work if preferences have nested intents: // // controllerClassName = XmlParserUtils.getController(mContext, attrs); diff --git a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java similarity index 51% rename from tests/robotests/src/com/android/settings/slices/SlicesDatabaseUtilsTest.java rename to tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java index f22e85ffdff..10e4b7694f9 100644 --- a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseUtilsTest.java +++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java @@ -20,9 +20,13 @@ import static com.android.settings.TestConfig.SDK_VERSION; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + import android.content.Context; import android.net.Uri; +import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.core.BasePreferenceController; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -37,7 +41,7 @@ import androidx.app.slice.Slice; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = SDK_VERSION) -public class SlicesDatabaseUtilsTest { +public class SliceBuilderUtilsTest { private final String KEY = "KEY"; private final String TITLE = "title"; @@ -65,17 +69,74 @@ public class SlicesDatabaseUtilsTest { @Test public void testGetPreferenceController_buildsMatchingController() { - BasePreferenceController controller = SliceBuilderUtils.getPreferenceController(mContext, - getDummyData()); + BasePreferenceController controller = SliceBuilderUtils.getPreferenceController( + mContext, getDummyData()); assertThat(controller).isInstanceOf(FakeToggleController.class); } + @Test + public void testDynamicSummary_returnsSliceSummary() { + SliceData data = getDummyData(); + FakePreferenceController controller = new FakePreferenceController(mContext, KEY); + + String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); + + assertThat(summary).isEqualTo(data.getSummary()); + } + + @Test + public void testDynamicSummary_returnsFragmentSummary() { + SliceData data = getDummyData(null); + FakePreferenceController controller = spy(new FakePreferenceController(mContext, KEY)); + String controllerSummary = "new_Summary"; + doReturn(controllerSummary).when(controller).getSummary(); + + String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); + + assertThat(summary).isEqualTo(controllerSummary); + } + + @Test + public void testDynamicSummary_returnsSliceScreenTitle() { + SliceData data = getDummyData(null); + FakePreferenceController controller = new FakePreferenceController(mContext, KEY); + + String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); + + assertThat(summary).isEqualTo(data.getScreenTitle()); + } + + @Test + public void testDynamicSummary_placeHolderString_returnsScreenTitle() { + SliceData data = getDummyData(mContext.getString(R.string.summary_placeholder)); + FakePreferenceController controller = new FakePreferenceController(mContext, KEY); + String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); + + assertThat(summary).isEqualTo(data.getScreenTitle()); + } + + @Test + public void testDynamicSummary_sliceDataAndFragmentPlaceholder_returnsSliceScreenTitle() { + String summaryPlaceholder = mContext.getString(R.string.summary_placeholder); + SliceData data = getDummyData(summaryPlaceholder); + FakePreferenceController controller = spy(new FakePreferenceController(mContext, KEY)); + doReturn(summaryPlaceholder).when(controller).getSummary(); + + String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); + + assertThat(summary).isEqualTo(data.getScreenTitle()); + } + private SliceData getDummyData() { + return getDummyData(SUMMARY); + } + + private SliceData getDummyData(String summary) { return new SliceData.Builder() .setKey(KEY) .setTitle(TITLE) - .setSummary(SUMMARY) + .setSummary(summary) .setScreenTitle(SCREEN_TITLE) .setIcon(ICON) .setFragmentName(FRAGMENT_NAME) From 45603a1524b75a3a59160f171d513b2b0febda17 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Tue, 16 Jan 2018 16:00:03 -0800 Subject: [PATCH 03/30] Show Toast with location of trace when trace is disabled - Rename Layer Trace development tile to Surface Flinger Trace Bug: 64831661 Test: Manually toggle trace Test: make RunSettingsRoboTests ROBOTEST_FILTER=LayerTraceTest && make RunSettingsRoboTests ROBOTEST_FILTER=WindowTraceTest Change-Id: I438efca251688774f0d6f29ba93d02d116f1e574 --- res/values/strings.xml | 2 +- .../development/qstile/DevelopmentTiles.java | 16 ++++++++++++++++ .../development/qstile/LayerTraceTest.java | 9 +++++++-- .../development/qstile/WindowTraceTest.java | 14 ++++++++++++-- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index cfefa55cc45..eba4fa0b29f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8732,7 +8732,7 @@ Window Trace - Layer Trace + Surface Trace Work profile settings diff --git a/src/com/android/settings/development/qstile/DevelopmentTiles.java b/src/com/android/settings/development/qstile/DevelopmentTiles.java index fea658869c2..38f95655168 100644 --- a/src/com/android/settings/development/qstile/DevelopmentTiles.java +++ b/src/com/android/settings/development/qstile/DevelopmentTiles.java @@ -16,6 +16,7 @@ package com.android.settings.development.qstile; +import android.content.Context; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; @@ -30,6 +31,7 @@ import android.view.IWindowManager; import android.view.ThreadedRenderer; import android.view.View; import android.view.WindowManagerGlobal; +import android.widget.Toast; import com.android.internal.app.LocalePicker; import com.android.settings.wrapper.IWindowManagerWrapper; @@ -145,12 +147,17 @@ public abstract class DevelopmentTiles extends TileService { public static class WindowTrace extends DevelopmentTiles { @VisibleForTesting IWindowManagerWrapper mWindowManager; + @VisibleForTesting + Toast mToast; @Override public void onCreate() { super.onCreate(); mWindowManager = new IWindowManagerWrapper(WindowManagerGlobal .getWindowManagerService()); + Context context = getApplicationContext(); + CharSequence text = "Trace written to /data/misc/wmtrace/wm_trace.pb"; + mToast = Toast.makeText(context, text, Toast.LENGTH_LONG); } @Override @@ -171,6 +178,7 @@ public abstract class DevelopmentTiles extends TileService { mWindowManager.startWindowTrace(); } else { mWindowManager.stopWindowTrace(); + mToast.show(); } } catch (RemoteException e) { Log.e(TAG, "Could not set window trace status." + e.toString()); @@ -188,11 +196,16 @@ public abstract class DevelopmentTiles extends TileService { static final int SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE = 1026; @VisibleForTesting IBinder mSurfaceFlinger; + @VisibleForTesting + Toast mToast; @Override public void onCreate() { super.onCreate(); mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger"); + Context context = getApplicationContext(); + CharSequence text = "Trace written to /data/misc/wmtrace/layers_trace.pb"; + mToast = Toast.makeText(context, text, Toast.LENGTH_LONG); } @Override @@ -230,6 +243,9 @@ public abstract class DevelopmentTiles extends TileService { data.writeInt(isEnabled ? 1 : 0); mSurfaceFlinger.transact(SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE, data, null, 0 /* flags */); + if (!isEnabled){ + mToast.show(); + } } } catch (RemoteException e) { Log.e(TAG, "Could not set layer tracing." + e.toString()); diff --git a/tests/robotests/src/com/android/settings/development/qstile/LayerTraceTest.java b/tests/robotests/src/com/android/settings/development/qstile/LayerTraceTest.java index 594b96c8e71..0e42759ad28 100644 --- a/tests/robotests/src/com/android/settings/development/qstile/LayerTraceTest.java +++ b/tests/robotests/src/com/android/settings/development/qstile/LayerTraceTest.java @@ -33,6 +33,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import android.os.IBinder; import android.os.RemoteException; +import android.widget.Toast; import com.android.settings.TestConfig; import com.android.settings.testutils.shadow.ShadowParcel; @@ -52,6 +53,8 @@ import org.robolectric.util.ReflectionHelpers; public class LayerTraceTest { @Mock private IBinder mSurfaceFlinger; + @Mock + private Toast mToast; private DevelopmentTiles.LayerTrace mLayerTraceTile; @@ -59,13 +62,14 @@ public class LayerTraceTest { public void setUp() { MockitoAnnotations.initMocks(this); mLayerTraceTile = spy(new DevelopmentTiles.LayerTrace()); - mLayerTraceTile.onCreate(); ReflectionHelpers.setField(mLayerTraceTile, "mSurfaceFlinger", mSurfaceFlinger); + ReflectionHelpers.setField(mLayerTraceTile, "mToast", mToast); } @After public void after() { verifyNoMoreInteractions(mSurfaceFlinger); + verifyNoMoreInteractions(mToast); } @Test @@ -106,12 +110,13 @@ public class LayerTraceTest { @Test @Config(shadows = {ShadowParcel.class}) - public void setIsEnableFalse_shouldDisableLayerTrace() throws RemoteException { + public void setIsEnableFalse_shouldDisableLayerTraceAndShowToast() throws RemoteException { mLayerTraceTile.setIsEnabled(false); assertThat(ShadowParcel.sWriteIntResult).isEqualTo(0); verify(mSurfaceFlinger) .transact(eq(SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE), any(), isNull(), eq(0 /* flags */)); + verify(mToast).show(); } @Test diff --git a/tests/robotests/src/com/android/settings/development/qstile/WindowTraceTest.java b/tests/robotests/src/com/android/settings/development/qstile/WindowTraceTest.java index 3c4d9baad3b..d8a8084e102 100644 --- a/tests/robotests/src/com/android/settings/development/qstile/WindowTraceTest.java +++ b/tests/robotests/src/com/android/settings/development/qstile/WindowTraceTest.java @@ -25,12 +25,14 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import android.os.RemoteException; +import android.widget.Toast; import com.android.settings.TestConfig; import com.android.settings.testutils.shadow.ShadowParcel; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.wrapper.IWindowManagerWrapper; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -44,6 +46,8 @@ import org.robolectric.util.ReflectionHelpers; public class WindowTraceTest { @Mock private IWindowManagerWrapper mWindowManager; + @Mock + private Toast mToast; private DevelopmentTiles.WindowTrace mWindowTrace; @@ -51,8 +55,13 @@ public class WindowTraceTest { public void setUp() { MockitoAnnotations.initMocks(this); mWindowTrace = spy(new DevelopmentTiles.WindowTrace()); - mWindowTrace.onCreate(); ReflectionHelpers.setField(mWindowTrace, "mWindowManager", mWindowManager); + ReflectionHelpers.setField(mWindowTrace, "mToast", mToast); + } + + @After + public void teardown() { + verifyNoMoreInteractions(mToast); } @Test @@ -83,9 +92,10 @@ public class WindowTraceTest { @Test @Config(shadows = {ShadowParcel.class}) - public void setIsEnableFalse_shouldDisableWindowTrace() throws RemoteException { + public void setIsEnableFalse_shouldDisableWindowTraceAndShowToast() throws RemoteException { mWindowTrace.setIsEnabled(false); verify(mWindowManager).stopWindowTrace(); + verify(mToast).show(); verifyNoMoreInteractions(mWindowManager); } From caee81b4e5e1165cc3145e7b4873e48521100c78 Mon Sep 17 00:00:00 2001 From: Michael Plass Date: Tue, 16 Jan 2018 17:02:55 -0800 Subject: [PATCH 04/30] Remove aggressive handover developer setting The developer setting for aggressive wifi to mobile data handover is no longer used by the framework, so it should not appear in the settings UI. Bug: 72063774 Test: m RunSettingsRoboTests -j40 Test: Manually check developer options, make sure aggressive handover is gone Change-Id: Id54c714fc82fb27abc0b4116f2b82be68cc6d151 --- res/xml/development_settings.xml | 5 - .../DevelopmentSettingsDashboardFragment.java | 1 - ...ggressiveHandoverPreferenceController.java | 85 ------------- ...ssiveHandoverPreferenceControllerTest.java | 112 ------------------ 4 files changed, 203 deletions(-) delete mode 100644 src/com/android/settings/development/WifiAggressiveHandoverPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/development/WifiAggressiveHandoverPreferenceControllerTest.java diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index aad5d2361b1..2b62964c194 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -202,11 +202,6 @@ android:title="@string/wifi_verbose_logging" android:summary="@string/wifi_verbose_logging_summary"/> - - 0; - mPreference.setChecked(enabled); - } - - @Override - protected void onDeveloperOptionsSwitchEnabled() { - mPreference.setEnabled(true); - } - - @Override - protected void onDeveloperOptionsSwitchDisabled() { - mWifiManager.enableAggressiveHandover(SETTING_VALUE_OFF); - mPreference.setChecked(false); - mPreference.setEnabled(false); - } -} diff --git a/tests/robotests/src/com/android/settings/development/WifiAggressiveHandoverPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/WifiAggressiveHandoverPreferenceControllerTest.java deleted file mode 100644 index ebda83749f3..00000000000 --- a/tests/robotests/src/com/android/settings/development/WifiAggressiveHandoverPreferenceControllerTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2017 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.development; - -import static com.android.settings.development.WifiAggressiveHandoverPreferenceController - .SETTING_VALUE_OFF; -import static com.android.settings.development.WifiAggressiveHandoverPreferenceController - .SETTING_VALUE_ON; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.wifi.WifiManager; -import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.PreferenceScreen; - -import com.android.settings.TestConfig; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class WifiAggressiveHandoverPreferenceControllerTest { - - @Mock - private Context mContext; - @Mock - private WifiManager mWifiManager; - @Mock - private SwitchPreference mPreference; - @Mock - private PreferenceScreen mPreferenceScreen; - - private WifiAggressiveHandoverPreferenceController mController; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager); - mController = new WifiAggressiveHandoverPreferenceController(mContext); - when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn( - mPreference); - mController.displayPreference(mPreferenceScreen); - } - - @Test - public void onPreferenceChange_settingEnabled_shouldEnableAggressiveHandover() { - mController.onPreferenceChange(mPreference, true /* new value */); - - verify(mWifiManager).enableAggressiveHandover(SETTING_VALUE_ON); - } - - @Test - public void onPreferenceChange_settingDisabled_shouldDisableAggressiveHandover() { - mController.onPreferenceChange(mPreference, false /* new value */); - - verify(mWifiManager).enableAggressiveHandover(SETTING_VALUE_OFF); - } - - @Test - public void updateState_settingEnabled_shouldEnablePreference() { - when(mWifiManager.getAggressiveHandover()).thenReturn(1); - mController.updateState(mPreference); - - verify(mPreference).setChecked(true); - } - - @Test - public void updateState_settingDisabled_shouldDisablePreference() { - when(mWifiManager.getAggressiveHandover()).thenReturn(0); - mController.updateState(mPreference); - - verify(mPreference).setChecked(false); - } - - @Test - public void onDeveloperOptionsSwitchEnabled_shouldEnablePreference() { - mController.onDeveloperOptionsSwitchEnabled(); - - verify(mPreference).setEnabled(true); - } - - @Test - public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() { - mController.onDeveloperOptionsSwitchDisabled(); - - verify(mWifiManager).enableAggressiveHandover(SETTING_VALUE_OFF); - verify(mPreference).setEnabled(false); - verify(mPreference).setChecked(false); - } -} From db9d09793fc186f664fa39f6c76cbd26550b6f0f Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Wed, 10 Jan 2018 13:56:31 +0100 Subject: [PATCH 05/30] DisplayCutout: Add emulation option to DeveloperSettings Bug: 65689439 Test: Go to Developer Settings > Toggle "Emulate display with a cutout" Change-Id: Id3387c026df9868d42e0a7b0d7e623115f41452b --- res/values/strings.xml | 3 + res/xml/development_settings.xml | 4 + .../DevelopmentSettingsDashboardFragment.java | 1 + ...lateDisplayCutoutPreferenceController.java | 122 +++++++++++++++ .../android/content/om/IOverlayManager.java | 6 +- .../src/android/content/om/OverlayInfo.java | 7 +- ...DisplayCutoutPreferenceControllerTest.java | 148 ++++++++++++++++++ 7 files changed, 289 insertions(+), 2 deletions(-) create mode 100644 src/com/android/settings/development/EmulateDisplayCutoutPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/development/EmulateDisplayCutoutPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 536604c3ecf..fa53a3afbfd 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8674,6 +8674,9 @@ Ranking object doesn\'t contain this key. + + Emulate a display with a cutout + Special app access diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index aad5d2361b1..62f69627f1f 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -356,6 +356,10 @@ android:key="density" android:title="@string/developer_smallest_width" /> + + Date: Wed, 17 Jan 2018 10:27:29 -0800 Subject: [PATCH 06/30] Moving Settings tests closer to the settings code Change-Id: Ia456db3a8728b35390963c989d5788f4f23806cd --- tests/uitests/Android.mk | 35 + tests/uitests/AndroidManifest.xml | 34 + tests/uitests/AndroidTest.xml | 27 + .../settings/ui/AboutPhoneSettingsTests.java | 224 +++++ .../ui/AccessibilitySettingsTests.java | 279 +++++++ .../settings/ui/AppsSettingsTests.java | 136 +++ .../ui/BluetoothNetworkSettingsTests.java | 163 ++++ .../settings/ui/ConnectedDeviceTests.java | 92 +++ .../settings/ui/DataUsageSettingsTests.java | 84 ++ .../settings/ui/DisplaySettingsTest.java | 268 ++++++ .../settings/ui/HomepageDisplayTests.java | 99 +++ .../settings/ui/LocationSettingsTests.java | 243 ++++++ .../ui/MoreWirelessSettingsTests.java | 126 +++ .../ui/NotificationSettingsTests.java | 158 ++++ .../ui/SecuritySettingsLaunchTest.java | 75 ++ .../settings/ui/SoundSettingsTest.java | 334 ++++++++ .../android/settings/ui/SyncSettingsTest.java | 70 ++ .../ui/WirelessNetworkSettingsTests.java | 777 ++++++++++++++++++ .../ui/testutils/SettingsTestUtils.java | 61 ++ 19 files changed, 3285 insertions(+) create mode 100644 tests/uitests/Android.mk create mode 100644 tests/uitests/AndroidManifest.xml create mode 100644 tests/uitests/AndroidTest.xml create mode 100644 tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/ConnectedDeviceTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/DataUsageSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java create mode 100644 tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/LocationSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/NotificationSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java create mode 100644 tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java create mode 100644 tests/uitests/src/com/android/settings/ui/SyncSettingsTest.java create mode 100644 tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java diff --git a/tests/uitests/Android.mk b/tests/uitests/Android.mk new file mode 100644 index 00000000000..23357e8c4c6 --- /dev/null +++ b/tests/uitests/Android.mk @@ -0,0 +1,35 @@ +# Copyright (C) 2018 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. + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PACKAGE_NAME := SettingsUITests +LOCAL_COMPATIBILITY_SUITE := device-tests +LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_MODULE_TAGS := tests +LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base +LOCAL_STATIC_JAVA_LIBRARIES := \ + app-helpers-base \ + launcher-helper-lib \ + settings-helper \ + timeresult-helper-lib \ + ub-uiautomator \ + sysui-helper \ + metrics-helper-lib \ + platform-test-annotations \ + +#LOCAL_SDK_VERSION := current + +include $(BUILD_PACKAGE) diff --git a/tests/uitests/AndroidManifest.xml b/tests/uitests/AndroidManifest.xml new file mode 100644 index 00000000000..06d74c681e7 --- /dev/null +++ b/tests/uitests/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/uitests/AndroidTest.xml b/tests/uitests/AndroidTest.xml new file mode 100644 index 00000000000..fbeea2db60c --- /dev/null +++ b/tests/uitests/AndroidTest.xml @@ -0,0 +1,27 @@ + + + + + + + diff --git a/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java new file mode 100644 index 00000000000..57f9bc2aedd --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.content.Intent; +import android.os.RemoteException; +import android.provider.Settings; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.Direction; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.Suppress; +import android.text.TextUtils; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +/** Verifies basic functionality of the About Phone screen */ +public class AboutPhoneSettingsTests extends InstrumentationTestCase { + private static final boolean LOCAL_LOGV = false; + private static final String TAG = "AboutPhoneSettingsTest"; + private static final int TIMEOUT = 2000; + private static final String SETTINGS_PACKAGE = "com.android.settings"; + + private UiDevice mDevice; + + // TODO: retrieve using name/ids from com.android.settings package + private static final String[] sResourceTexts = { + "Status", + "Legal information", + "Regulatory labels", + "Model", + "Android version", + "Android security patch level", + "Baseband version", + "Kernel version", + "Build number" + }; + + private static final String[] sClickableResourceTexts = { + "Status", "Legal information", "Regulatory labels", + }; + + @Override + public void setUp() throws Exception { + if (LOCAL_LOGV) { + Log.d(TAG, "-------"); + } + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("Failed to freeze device orientaion", e); + } + + // make sure we are in a clean state before starting the test + mDevice.pressHome(); + Thread.sleep(TIMEOUT * 2); + launchAboutPhoneSettings(Settings.ACTION_DEVICE_INFO_SETTINGS); + // TODO: make sure we are always at the top of the app + // currently this will fail if the user has navigated into submenus + UiObject2 view = + mDevice.wait( + Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), TIMEOUT); + assertNotNull("Could not find main About Phone screen", view); + view.scroll(Direction.UP, 1.0f); + } + + @Override + protected void tearDown() throws Exception { + // Adding an extra pressBack so we exit About Phone Settings + // and finish the test cleanly + mDevice.pressBack(); + mDevice.pressHome(); // finish settings activity + mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating + super.tearDown(); + } + + private void launchAboutPhoneSettings(String aboutSetting) throws Exception { + Intent aboutIntent = new Intent(aboutSetting); + aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + getInstrumentation().getContext().startActivity(aboutIntent); + } + + /** + * Callable actions that can be taken when a UIObject2 is found + * + * @param device The current UiDevice + * @param item The UiObject2 that was found and can be acted on + * + * @return {@code true} if the call was successful, and {@code false} otherwise + */ + public interface UIObject2Callback { + boolean call(UiDevice device, UiObject2 item) throws Exception; + } + + /** + * Clicks the given item and then presses the Back button + * + *

Used to test whether a given UiObject2 can be successfully clicked. + * Presses Back to restore state to the previous screen. + * + * @param device The device that can be used to press Back + * @param item The item to click + * + * @return {@code true} if clicking the item succeeded, and {@code false} otherwise + */ + public class UiObject2Clicker implements UIObject2Callback { + public boolean call(UiDevice device, UiObject2 item) throws Exception { + item.click(); + Thread.sleep(TIMEOUT * 2); // give UI time to finish animating + boolean pressWorked = device.pressBack(); + Thread.sleep(TIMEOUT * 2); + return pressWorked; + } + } + + /** + * Removes items found in the view and optionally takes some action. + * + * @param device The current UiDevice + * @param itemsLeftToFind The items to search for in the current view + * @param action Action to call on each item that is found; pass {@code null} to take no action + */ + private void removeItemsAndTakeAction( + UiDevice device, ArrayList itemsLeftToFind, UIObject2Callback action) throws Exception { + for (Iterator iterator = itemsLeftToFind.iterator(); iterator.hasNext(); ) { + String itemText = iterator.next(); + UiObject2 item = device.wait(Until.findObject(By.text(itemText)), TIMEOUT); + if (item != null) { + if (LOCAL_LOGV) { + Log.d(TAG, itemText + " is present"); + } + iterator.remove(); + if (action != null) { + boolean success = action.call(device, item); + assertTrue("Calling action after " + itemText + " did not work", success); + } + } else { + if (LOCAL_LOGV) { + Log.d(TAG, "Could not find " + itemText); + } + } + } + } + + /** + * Searches for UI elements in the current view and optionally takes some action. + * + *

Will scroll down the screen until it has found all elements or reached the bottom. + * This allows elements to be found and acted on even if they change order. + * + * @param device The current UiDevice + * @param itemsToFind The items to search for in the current view + * @param action Action to call on each item that is found; pass {@code null} to take no action + */ + public void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind, UIObject2Callback action) + throws Exception { + + ArrayList itemsLeftToFind = new ArrayList(Arrays.asList(itemsToFind)); + assertFalse( + "There must be at least one item to search for on the screen!", + itemsLeftToFind.isEmpty()); + + if (LOCAL_LOGV) { + Log.d(TAG, "items: " + TextUtils.join(", ", itemsLeftToFind)); + } + boolean canScrollDown = true; + while (canScrollDown && !itemsLeftToFind.isEmpty()) { + removeItemsAndTakeAction(device, itemsLeftToFind, action); + + // when we've finished searching the current view, scroll down + UiObject2 view = + device.wait( + Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), + TIMEOUT * 2); + if (view != null) { + canScrollDown = view.scroll(Direction.DOWN, 1.0f); + } else { + canScrollDown = false; + } + } + // check the last items once we have reached the bottom of the view + removeItemsAndTakeAction(device, itemsLeftToFind, action); + + assertTrue( + "The following items were not found on the screen: " + + TextUtils.join(", ", itemsLeftToFind), + itemsLeftToFind.isEmpty()); + } + + @MediumTest // UI interaction + public void testAllMenuEntriesExist() throws Exception { + searchForItemsAndTakeAction(mDevice, sResourceTexts, null); + } + + // Suppressing this test as it might be causing other test failures + // Will verify that this test is the cause before proceeding with solution + @Suppress + @MediumTest // UI interaction + public void testClickableEntriesCanBeClicked() throws Exception { + searchForItemsAndTakeAction(mDevice, sClickableResourceTexts, new UiObject2Clicker()); + } +} diff --git a/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java b/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java new file mode 100644 index 00000000000..83afa6583f8 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.content.Context; +import android.net.wifi.WifiManager; +import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; +import android.provider.Settings; +import android.support.test.metricshelper.MetricsAsserts; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.Direction; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.system.helpers.SettingsHelper; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.Suppress; + +import android.metrics.MetricsReader; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + +public class AccessibilitySettingsTests extends InstrumentationTestCase { + + private static final String SETTINGS_PACKAGE = "com.android.settings"; + private static final int TIMEOUT = 2000; + private UiDevice mDevice; + private MetricsReader mMetricsReader; + + @Override + public void setUp() throws Exception { + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientaion", e); + } + mMetricsReader = new MetricsReader(); + // Clear out old logs + mMetricsReader.checkpoint(); + } + + @Override + protected void tearDown() throws Exception { + // Need to finish settings activity + mDevice.pressBack(); + mDevice.pressHome(); + mDevice.waitForIdle(); + super.tearDown(); + } + + @Presubmit + @MediumTest + public void testHighContrastTextOn() throws Exception { + verifyAccessibilitySettingOnOrOff("High contrast text", + Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0, 1); + } + + @Presubmit + @MediumTest + public void testHighContrastTextOff() throws Exception { + verifyAccessibilitySettingOnOrOff("High contrast text", + Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 1, 0); + } + + @Presubmit + @MediumTest + public void testPowerButtonEndsCallOn() throws Exception { + verifyAccessibilitySettingOnOrOff("Power button ends call", + Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 1, 2); + } + + @Presubmit + @MediumTest + public void testPowerButtonEndsCallOff() throws Exception { + verifyAccessibilitySettingOnOrOff("Power button ends call", + Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 2, 1); + } + + /* Suppressing these four tests. The settings don't play + * nice with Settings.System.putInt or Settings.Secure.putInt. + * Need further clarification. Filed bug b/27792029 + */ + @Suppress + @MediumTest + public void testAutoRotateScreenOn() throws Exception { + verifyAccessibilitySettingOnOrOff("Auto-rotate screen", + Settings.System.ACCELEROMETER_ROTATION, 0, 1); + } + + @Suppress + @MediumTest + public void testAutoRotateScreenOff() throws Exception { + verifyAccessibilitySettingOnOrOff("Auto-rotate screen", + Settings.System.ACCELEROMETER_ROTATION, 1, 0); + } + + @Suppress + @MediumTest + public void testMonoAudioOn() throws Exception { + verifyAccessibilitySettingOnOrOff("Mono audio", + Settings.System.MASTER_MONO, 0, 1); + } + + @Suppress + @MediumTest + public void testMonoAudioOff() throws Exception { + verifyAccessibilitySettingOnOrOff("Mono audio", + Settings.System.MASTER_MONO, 1, 0); + } + + @Presubmit + @MediumTest + public void testLargeMousePointerOn() throws Exception { + verifyAccessibilitySettingOnOrOff("Large mouse pointer", + Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 0, 1); + } + + @Presubmit + @MediumTest + public void testLargeMousePointerOff() throws Exception { + verifyAccessibilitySettingOnOrOff("Large mouse pointer", + Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 1, 0); + } + + @Presubmit + @MediumTest + public void testColorCorrection() throws Exception { + verifySettingToggleAfterScreenLoad("Color correction", + Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED); + MetricsAsserts.assertHasVisibilityLog("Missing color correction log", + mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_DALTONIZER, true); + } + + // Suppressing this test, since UiAutomator + talkback don't play nice + @Suppress + @MediumTest + public void testTalkback() throws Exception { + verifySettingToggleAfterScreenLoad("TalkBack", + Settings.Secure.ACCESSIBILITY_ENABLED); + } + + @Presubmit + @MediumTest + public void testCaptions() throws Exception { + verifySettingToggleAfterScreenLoad("Captions", + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED); + MetricsAsserts.assertHasVisibilityLog("Missing captions log", + mMetricsReader, MetricsEvent.ACCESSIBILITY_CAPTION_PROPERTIES, true); + } + + @Presubmit + @MediumTest + public void testMagnificationGesture() throws Exception { + verifySettingToggleAfterScreenLoad("Magnification", "Magnify with triple-tap", + Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED); + MetricsAsserts.assertHasVisibilityLog("Missing magnification log", + mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION, true); + } + + @MediumTest + public void testClickAfterPointerStopsMoving() throws Exception { + verifySettingToggleAfterScreenLoad("Click after pointer stops moving", + Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED); + } + + @MediumTest + public void testAccessibilitySettingsLoadLog() throws Exception { + launchAccessibilitySettings(); + MetricsAsserts.assertHasVisibilityLog("Missing accessibility settings load log", + mMetricsReader, MetricsEvent.ACCESSIBILITY, true); + } + + public void launchAccessibilitySettings() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_ACCESSIBILITY_SETTINGS); + } + + private void verifyAccessibilitySettingOnOrOff(String settingText, + String settingFlag, int initialFlagValue, int expectedFlagValue) + throws Exception { + Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), + settingFlag, initialFlagValue); + launchAccessibilitySettings(); + UiObject2 settingsTitle = findItemOnScreen(settingText); + settingsTitle.click(); + Thread.sleep(TIMEOUT); + int settingValue = Settings.Secure + .getInt(getInstrumentation().getContext().getContentResolver(), settingFlag); + assertEquals(settingText + " not correctly set after toggle", + expectedFlagValue, settingValue); + } + + private void verifySettingToggleAfterScreenLoad(String settingText, String settingFlag) + throws Exception { + verifySettingToggleAfterScreenLoad(settingText, null, settingFlag); + } + + private void verifySettingToggleAfterScreenLoad + (String settingText, String subSetting, String settingFlag) throws Exception { + // Load accessibility settings + launchAccessibilitySettings(); + Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), + settingFlag, 0); + Thread.sleep(TIMEOUT); + // Tap on setting required + UiObject2 settingTitle = findItemOnScreen(settingText); + // Load screen + settingTitle.click(); + Thread.sleep(TIMEOUT); + if (subSetting != null) { + UiObject2 subSettingObject = findItemOnScreen(subSetting); + subSettingObject.click(); + Thread.sleep(TIMEOUT); + } + // Toggle value + UiObject2 settingToggle = mDevice.wait(Until.findObject(By.text("Off")), + TIMEOUT); + settingToggle.click(); + dismissOpenDialog(); + Thread.sleep(TIMEOUT); + // Assert new value + int settingValue = Settings.Secure. + getInt(getInstrumentation().getContext().getContentResolver(), settingFlag); + assertEquals(settingText + " value not set correctly", 1, settingValue); + // Toogle value + settingToggle.click(); + dismissOpenDialog(); + mDevice.pressBack(); + Thread.sleep(TIMEOUT); + // Assert reset to old value + settingValue = Settings.Secure. + getInt(getInstrumentation().getContext().getContentResolver(), settingFlag); + assertEquals(settingText + " value not set correctly", 0, settingValue); + } + + private UiObject2 findItemOnScreen(String item) throws Exception { + int count = 0; + UiObject2 settingsPanel = mDevice.wait(Until.findObject + (By.res(SETTINGS_PACKAGE, "list")), TIMEOUT); + while (settingsPanel.fling(Direction.UP) && count < 3) { + count++; + } + count = 0; + UiObject2 setting = null; + while(count < 3 && setting == null) { + setting = mDevice.wait(Until.findObject(By.text(item)), TIMEOUT); + if (setting == null) { + settingsPanel.scroll(Direction.DOWN, 1.0f); + } + count++; + } + return setting; + } + + private void dismissOpenDialog() throws Exception { + UiObject2 okButton = mDevice.wait(Until.findObject + (By.res("android:id/button1")), TIMEOUT*2); + if (okButton != null) { + okButton.click(); + } + } +} diff --git a/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java b/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java new file mode 100644 index 00000000000..6be49d6d1ca --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.content.Intent; +import android.os.RemoteException; +import android.provider.Settings; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.Direction; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.system.helpers.ActivityHelper; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.text.TextUtils; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +/** Verifies basic functionality of the About Phone screen */ +public class AppsSettingsTests extends InstrumentationTestCase { + private static final boolean LOCAL_LOGV = false; + private static final String SETTINGS_PACKAGE = "com.android.settings"; + private static final String TAG = "AboutPhoneSettingsTest"; + private static final int TIMEOUT = 2000; + private ActivityHelper mActivityHelper = null; + + private UiDevice mDevice; + + private static final String[] sResourceTexts = { + "Storage", + "Data usage", + "Permissions", + "App notifications", + "Open by default", + "Battery", + "Memory" + }; + + @Override + public void setUp() throws Exception { + if (LOCAL_LOGV) { + Log.d(TAG, "-------"); + } + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + mActivityHelper = ActivityHelper.getInstance(); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("Failed to freeze device orientaion", e); + } + + // make sure we are in a clean state before starting the test + mDevice.pressHome(); + Thread.sleep(TIMEOUT * 2); + launchAppsSettings(); + UiObject2 view = + mDevice.wait( + Until.findObject(By.text("All apps")), TIMEOUT); + assertNotNull("Could not find Settings > Apps screen", view); + } + + @Override + protected void tearDown() throws Exception { + mDevice.pressBack(); + mDevice.pressHome(); // finish settings activity + mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating + super.tearDown(); + } + + @MediumTest + public void testAppSettingsListForCalculator() { + UiObject2 calculator = mDevice.wait( + Until.findObject(By.text("Calculator")), TIMEOUT); + calculator.click(); + for (String setting : sResourceTexts) { + UiObject2 appSetting = + mDevice.wait( + Until.findObject(By.text(setting)), TIMEOUT); + assertNotNull("Missing setting for Calculator: " + setting, appSetting); + appSetting.scroll(Direction.DOWN, 10.0f); + } + } + + @MediumTest + public void testDisablingAndEnablingSystemApp() throws Exception { + launchAppsSettings(); + UiObject2 calculator = mDevice.wait( + Until.findObject(By.text("Calculator")), TIMEOUT); + calculator.click(); + mDevice.waitForIdle(TIMEOUT); + UiObject2 appInfoList = mDevice.wait( + Until.findObject(By.res(SETTINGS_PACKAGE, "list")), TIMEOUT); + appInfoList.scroll(Direction.DOWN, 100.0f); + UiObject2 disableButton = mDevice.wait( + Until.findObject(By.text("DISABLE")), TIMEOUT); + disableButton.click(); + mDevice.waitForIdle(TIMEOUT); + // Click on "Disable App" on dialog. + mDevice.wait( + Until.findObject(By.text("DISABLE APP")), TIMEOUT).click(); + mDevice.waitForIdle(TIMEOUT); + UiObject2 enableButton = mDevice.wait( + Until.findObject(By.text("ENABLE")), TIMEOUT); + assertNotNull("App not disabled successfully", enableButton); + enableButton.click(); + mDevice.waitForIdle(TIMEOUT); + disableButton = mDevice.wait( + Until.findObject(By.text("DISABLE")), TIMEOUT); + assertNotNull("App not enabled successfully", disableButton); + } + + private void launchAppsSettings() throws Exception { + Intent appsSettingsIntent = new + Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS); + mActivityHelper.launchIntent(appsSettingsIntent); + } +} diff --git a/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java b/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java new file mode 100644 index 00000000000..d41be9cd352 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.content.Intent; +import android.metrics.MetricsReader; +import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; +import android.provider.Settings; +import android.support.test.metricshelper.MetricsAsserts; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.BySelector; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + +public class BluetoothNetworkSettingsTests extends InstrumentationTestCase { + + private static final String SETTINGS_PACKAGE = "com.android.settings"; + private static final int TIMEOUT = 2000; + private static final int LONG_TIMEOUT = 40000; + private UiDevice mDevice; + private MetricsReader mMetricsReader; + + @Override + public void setUp() throws Exception { + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientaion", e); + } + mMetricsReader = new MetricsReader(); + // Clear out old logs + mMetricsReader.checkpoint(); + } + + @Override + protected void tearDown() throws Exception { + mDevice.pressBack(); + mDevice.pressHome(); + mDevice.waitForIdle(); + super.tearDown(); + } + + @Presubmit + @MediumTest + public void testBluetoothEnabled() throws Exception { + verifyBluetoothOnOrOff(true); + MetricsAsserts.assertHasActionLog("missing bluetooth toggle log", + mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE); + } + + @Presubmit + @MediumTest + public void testBluetoothDisabled() throws Exception { + verifyBluetoothOnOrOff(false); + MetricsAsserts.assertHasActionLog("missing bluetooth toggle log", + mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE); + } + + @MediumTest + public void testRenameOption() throws Exception { + launchBluetoothSettings(); + verifyUiObjectClicked(By.text("Device name"), "Rename preference"); + verifyUiObjectClicked(By.text("CANCEL"), "CANCEL button"); + + MetricsAsserts.assertHasActionLog("missing bluetooth rename device log", + mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_RENAME); + MetricsAsserts.assertHasVisibilityLog("missing bluetooth rename dialog log", + mMetricsReader, MetricsEvent.DIALOG_BLUETOOTH_RENAME, true); + } + + @MediumTest + public void testReceivedFilesOption() throws Exception { + launchBluetoothSettings(); + verifyUiObjectClicked(By.text("Received files"), "Received files preference"); + + MetricsAsserts.assertHasActionLog("missing bluetooth received files log", + mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_FILES); + } + + @MediumTest + public void testHelpFeedbackOverflowOption() throws Exception { + launchBluetoothSettings(); + + // Verify help & feedback + assertNotNull("Help & feedback item not found under Bluetooth Settings", + mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT)); + } + + public void launchBluetoothSettings() throws Exception { + Intent btIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); + btIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + getInstrumentation().getContext().startActivity(btIntent); + Thread.sleep(TIMEOUT * 2); + } + + /** + * Find the {@link UiObject2} by {@code itemSelector} and try to click it if possible. + * + * If not find, throw assertion error + * @param itemSelector used to find the {@link UiObject2} + * @param text the description of the {@link UiObject2} + */ + private void verifyUiObjectClicked(BySelector itemSelector, String text) throws Exception { + UiObject2 uiObject2 = mDevice.wait(Until.findObject(itemSelector), TIMEOUT); + assertNotNull(text + "is not present in bluetooth settings page", uiObject2); + uiObject2.click(); + } + + /** + * Toggles the Bluetooth switch and verifies that the change is reflected in Settings + * + * @param verifyOn set to whether you want the setting turned On or Off + */ + private void verifyBluetoothOnOrOff(boolean verifyOn) throws Exception { + String switchText = "ON"; + BluetoothAdapter bluetoothAdapter = ((BluetoothManager) getInstrumentation().getContext() + .getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + if (verifyOn) { + switchText = "OFF"; + bluetoothAdapter.disable(); + } else { + bluetoothAdapter.enable(); + } + launchBluetoothSettings(); + mDevice.wait(Until + .findObject(By.res(SETTINGS_PACKAGE, "switch_widget").text(switchText)), TIMEOUT) + .click(); + Thread.sleep(TIMEOUT); + String bluetoothValue = + Settings.Global.getString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.BLUETOOTH_ON); + if (verifyOn) { + assertEquals("1", bluetoothValue); + } else { + assertEquals("0", bluetoothValue); + } + } +} diff --git a/tests/uitests/src/com/android/settings/ui/ConnectedDeviceTests.java b/tests/uitests/src/com/android/settings/ui/ConnectedDeviceTests.java new file mode 100644 index 00000000000..971d724d040 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/ConnectedDeviceTests.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.content.Context; +import android.content.Intent; +import android.nfc.NfcAdapter; +import android.nfc.NfcManager; +import android.os.RemoteException; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@MediumTest +@RunWith(AndroidJUnit4.class) +public class ConnectedDeviceTests { + + private static final String SETTINGS_PACKAGE = "com.android.settings"; + private static final int TIMEOUT = 2000; + private UiDevice mDevice; + + @Before + public void setUp() throws Exception { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientation", e); + } + } + + @After + public void tearDown() throws Exception { + mDevice.pressBack(); + mDevice.pressHome(); + } + + // This NFC toggle test is set up this way since there's no way to set + // the NFC flag to enabled or disabled without touching UI. + // This way, we get coverage for whether or not the toggle button works. + @Test + public void testNFCToggle() throws Exception { + NfcManager manager = (NfcManager) InstrumentationRegistry.getTargetContext() + .getSystemService(Context.NFC_SERVICE); + NfcAdapter nfcAdapter = manager.getDefaultAdapter(); + boolean nfcInitiallyEnabled = nfcAdapter.isEnabled(); + InstrumentationRegistry.getContext().startActivity(new Intent() + .setClassName( + SETTINGS_PACKAGE, + "com.android.settings.Settings$ConnectedDeviceDashboardActivity")); + UiObject2 nfcSetting = mDevice.wait(Until.findObject(By.text("NFC")), TIMEOUT); + nfcSetting.click(); + Thread.sleep(TIMEOUT * 2); + if (nfcInitiallyEnabled) { + assertFalse("NFC wasn't disabled on toggle", nfcAdapter.isEnabled()); + nfcSetting.click(); + Thread.sleep(TIMEOUT * 2); + assertTrue("NFC wasn't enabled on toggle", nfcAdapter.isEnabled()); + } else { + assertTrue("NFC wasn't enabled on toggle", nfcAdapter.isEnabled()); + nfcSetting.click(); + Thread.sleep(TIMEOUT * 2); + assertFalse("NFC wasn't disabled on toggle", nfcAdapter.isEnabled()); + } + } +} diff --git a/tests/uitests/src/com/android/settings/ui/DataUsageSettingsTests.java b/tests/uitests/src/com/android/settings/ui/DataUsageSettingsTests.java new file mode 100644 index 00000000000..725ba5cf635 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/DataUsageSettingsTests.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.os.RemoteException; +import android.provider.Settings; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.Until; +import android.system.helpers.SettingsHelper; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.Suppress; + +public class DataUsageSettingsTests extends InstrumentationTestCase { + + private static final String SETTINGS_PACKAGE = "com.android.settings"; + private static final int TIMEOUT = 2000; + private UiDevice mDevice; + + @Override + public void setUp() throws Exception { + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientaion", e); + } + } + + @Override + protected void tearDown() throws Exception { + // Need to finish settings activity + mDevice.pressBack(); + mDevice.pressHome(); + super.tearDown(); + } + + @MediumTest + public void testElementsOnDataUsageScreen() throws Exception { + launchDataUsageSettings(); + assertNotNull("Data usage element not found", + mDevice.wait(Until.findObject(By.text("Usage")), + TIMEOUT)); + assertNotNull("Data usage bar not found", + mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, + "color_bar")), TIMEOUT)); + assertNotNull("WiFi Data usage element not found", + mDevice.wait(Until.findObject(By.text("Wi-Fi data usage")), + TIMEOUT)); + assertNotNull("Network restrictions element not found", + mDevice.wait(Until.findObject(By.text("Network restrictions")), + TIMEOUT)); + } + + public void launchDataUsageSettings() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_SETTINGS); + mDevice.wait(Until + .findObject(By.text("Network & Internet")), TIMEOUT) + .click(); + Thread.sleep(TIMEOUT * 2); + assertNotNull("Network & internet screen not loaded", mDevice.wait( + Until.findObject(By.text("Data usage")), TIMEOUT)); + mDevice.wait(Until + .findObject(By.text("Data usage")), TIMEOUT) + .click(); + } +} diff --git a/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java b/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java new file mode 100644 index 00000000000..0b7402d76f2 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.content.ContentResolver; +import android.platform.test.annotations.Presubmit; +import android.provider.Settings; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.system.helpers.SettingsHelper; +import android.system.helpers.SettingsHelper.SettingsType; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.Suppress; + +import java.util.regex.Pattern; + +public class DisplaySettingsTest extends InstrumentationTestCase { + + private static final String PAGE = Settings.ACTION_DISPLAY_SETTINGS; + private static final int TIMEOUT = 2000; + private static final FontSetting FONT_SMALL = new FontSetting("Small", 0.85f); + private static final FontSetting FONT_NORMAL = new FontSetting("Default", 1.00f); + private static final FontSetting FONT_LARGE = new FontSetting("Large", 1.15f); + private static final FontSetting FONT_HUGE = new FontSetting("Largest", 1.30f); + + private UiDevice mDevice; + private ContentResolver mResolver; + private SettingsHelper mHelper; + + @Override + public void setUp() throws Exception { + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + mDevice.setOrientationNatural(); + mResolver = getInstrumentation().getContext().getContentResolver(); + mHelper = new SettingsHelper(); + } + + @Override + public void tearDown() throws Exception { + // reset settings we touched that may impact others + Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f); + mDevice.waitForIdle(); + super.tearDown(); + } + + @Presubmit + @MediumTest + public void testAdaptiveBrightness() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(true); + Thread.sleep(1000); + + assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness", + Settings.System.SCREEN_BRIGHTNESS_MODE)); + assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness", + Settings.System.SCREEN_BRIGHTNESS_MODE)); + } + + + // blocked on b/27487224 + @MediumTest + @Suppress + public void testDaydreamToggle() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + clickMore(); + Pattern p = Pattern.compile("On|Off"); + mHelper.clickSetting("Screen saver"); + Thread.sleep(1000); + try { + assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p, + Settings.Secure.SCREENSAVER_ENABLED, false)); + assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p, + Settings.Secure.SCREENSAVER_ENABLED, false)); + } finally { + mDevice.pressBack(); + } + } + + @MediumTest + public void testAccelRotation() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(true); + clickMore(); + Thread.sleep(4000); + int currentAccelSetting = Settings.System.getInt( + mResolver, Settings.System.ACCELEROMETER_ROTATION); + mHelper.clickSetting("Auto-rotate screen"); + int newAccelSetting = Settings.System.getInt( + mResolver, Settings.System.ACCELEROMETER_ROTATION); + assertTrue("Accelorometer setting unchanged after toggle", currentAccelSetting != newAccelSetting); + mHelper.clickSetting("Auto-rotate screen"); + int revertedAccelSetting = Settings.System.getInt( + mResolver, Settings.System.ACCELEROMETER_ROTATION); + assertTrue("Accelorometer setting unchanged after toggle", revertedAccelSetting != newAccelSetting); + } + + @MediumTest + public void testDaydream() throws Exception { + Settings.Secure.putInt(mResolver, Settings.Secure.SCREENSAVER_ENABLED, 1); + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + clickMore(); + mHelper.scrollVert(false); + mDevice.wait(Until.findObject(By.text("Screen saver")), TIMEOUT).click(); + try { + assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE, + "Current screen saver", "Clock", Settings.Secure.SCREENSAVER_COMPONENTS, + "com.google.android.deskclock/com.android.deskclock.Screensaver")); + assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE, + "Current screen saver", "Colors", Settings.Secure.SCREENSAVER_COMPONENTS, + "com.android.dreams.basic/com.android.dreams.basic.Colors")); + assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE, + "Current screen saver", "Photos", Settings.Secure.SCREENSAVER_COMPONENTS, + "com.google.android.apps.photos/com.google.android.apps.photos.daydream" + + ".PhotosDreamService")); + } finally { + mDevice.pressBack(); + Thread.sleep(2000); + } + } + + @Presubmit + @MediumTest + public void testSleep15Seconds() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(true); + assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, + "Sleep", "15 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "15000")); + } + + @MediumTest + public void testSleep30Seconds() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(true); + assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, + "Sleep", "30 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "30000")); + } + + @MediumTest + public void testSleep1Minute() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(true); + assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, + "Sleep", "1 minute", Settings.System.SCREEN_OFF_TIMEOUT, "60000")); + } + + @MediumTest + public void testSleep2Minutes() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(true); + assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, + "Sleep", "2 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "120000")); + } + + @MediumTest + public void testSleep5Minutes() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(true); + assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, + "Sleep", "5 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "300000")); + } + + @MediumTest + public void testSleep10Minutes() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(true); + assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, + "Sleep", "10 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "600000")); + } + + @MediumTest + public void testSleep30Minutes() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(true); + assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, + "Sleep", "30 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "1800000")); + } + + @Presubmit + @MediumTest + public void testFontSizeLarge() throws Exception { + verifyFontSizeSetting(1.00f, FONT_LARGE); + // Leaving the font size at large can make later tests fail, so reset it + Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f); + // It takes a second for the new font size to be picked up + Thread.sleep(2000); + } + + @MediumTest + public void testFontSizeDefault() throws Exception { + verifyFontSizeSetting(1.15f, FONT_NORMAL); + } + + @MediumTest + public void testFontSizeLargest() throws Exception { + verifyFontSizeSetting(1.00f, FONT_HUGE); + // Leaving the font size at huge can make later tests fail, so reset it + Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f); + // It takes a second for the new font size to be picked up + Thread.sleep(2000); + } + + @MediumTest + public void testFontSizeSmall() throws Exception { + verifyFontSizeSetting(1.00f, FONT_SMALL); + } + + private void verifyFontSizeSetting(float resetValue, FontSetting setting) + throws Exception { + Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, resetValue); + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + clickMore(); + mHelper.clickSetting("Font size"); + try { + mDevice.wait(Until.findObject(By.desc(setting.getName())), TIMEOUT).click(); + Thread.sleep(1000); + float changedValue = Settings.System.getFloat( + mResolver, Settings.System.FONT_SCALE); + assertEquals(setting.getSize(), changedValue, 0.0001); + } finally { + // Make sure to back out of the font menu + mDevice.pressBack(); + } + } + + private void clickMore() throws InterruptedException { + UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT); + if (more != null) { + more.click(); + Thread.sleep(TIMEOUT); + } + } + + private static class FontSetting { + private final String mSizeName; + private final float mSizeVal; + + public FontSetting(String sizeName, float sizeVal) { + mSizeName = sizeName; + mSizeVal = sizeVal; + } + + public String getName() { + return mSizeName; + } + + public float getSize() { + return mSizeVal; + } + } +} diff --git a/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java new file mode 100644 index 00000000000..7931d30edd2 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; +import android.provider.Settings; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.Direction; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.system.helpers.SettingsHelper; + +import com.android.settings.ui.testutils.SettingsTestUtils; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE; +import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT; + +@MediumTest +@RunWith(AndroidJUnit4.class) +public class HomepageDisplayTests { + + private static final String[] HOMEPAGE_ITEMS = { + "Network & internet", + "Connected devices", + "Apps & notifications", + "Battery", + "Display", + "Sound", + "Storage", + "Security & location", + "Users & accounts", + "Accessibility", + "System", + "Support & tips" + }; + + private UiDevice mDevice; + private SettingsHelper mSettingsHelper; + + @Before + public void setUp() throws Exception { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + mSettingsHelper = new SettingsHelper(); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientaion", e); + } + } + + @After + public void tearDown() throws Exception { + // Need to finish settings activity + mDevice.pressHome(); + } + + @Presubmit + @Test + public void testHomepageCategory() throws Exception { + // Launch Settings + SettingsHelper.launchSettingsPage( + InstrumentationRegistry.getContext(), Settings.ACTION_SETTINGS); + + // Scroll to top + final UiObject2 view = mDevice.wait( + Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")), + TIMEOUT); + view.scroll(Direction.UP, 100f); + + // Inspect each item + for (String item : HOMEPAGE_ITEMS) { + SettingsTestUtils.assertTitleMatch(mDevice, item); + } + } +} diff --git a/tests/uitests/src/com/android/settings/ui/LocationSettingsTests.java b/tests/uitests/src/com/android/settings/ui/LocationSettingsTests.java new file mode 100644 index 00000000000..b4a1baa8c23 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/LocationSettingsTests.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; +import android.provider.Settings; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.Direction; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.system.helpers.SettingsHelper; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; + + +public class LocationSettingsTests extends InstrumentationTestCase { + + private static final String SETTINGS_PACKAGE = "com.android.settings"; + private static final int TIMEOUT = 2000; + private UiDevice mDevice; + + @Override + public void setUp() throws Exception { + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientaion", e); + } + } + + @Override + protected void tearDown() throws Exception { + mDevice.pressBack(); + mDevice.pressHome(); + super.tearDown(); + } + + @MediumTest + public void testLoadingLocationSettings () throws Exception { + // Load Security + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_SECURITY_SETTINGS); + + SettingsHelper helper = new SettingsHelper(); + helper.scrollVert(true); + // Tap on location + UiObject2 settingsPanel = mDevice.wait(Until.findObject + (By.res(SETTINGS_PACKAGE, "main_content")), TIMEOUT); + int count = 0; + UiObject2 locationTitle = null; + while(count < 6 && locationTitle == null) { + locationTitle = mDevice.wait(Until.findObject(By.text("Location")), TIMEOUT); + if (locationTitle == null) { + settingsPanel.scroll(Direction.DOWN, 1.0f); + } + count++; + } + // Verify location settings loads. + locationTitle.click(); + Thread.sleep(TIMEOUT); + assertNotNull("Location screen has not loaded correctly", + mDevice.wait(Until.findObject(By.text("Location services")), TIMEOUT)); + } + + @Presubmit + @MediumTest + public void testLocationSettingOn() throws Exception { + verifyLocationSettingsOnOrOff(true); + } + + @MediumTest + public void testLocationSettingOff() throws Exception { + verifyLocationSettingsOnOrOff(false); + } + + @MediumTest + public void testLocationDeviceOnlyMode() throws Exception { + // Changing the value from default before testing the toggle to Device only mode + Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), + Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY); + dismissAlertDialogs(); + Thread.sleep(TIMEOUT); + verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_SENSORS_ONLY); + } + + @MediumTest + public void testLocationBatterySavingMode() throws Exception { + Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), + Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY); + Thread.sleep(TIMEOUT); + verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_BATTERY_SAVING); + } + + @MediumTest + public void testLocationHighAccuracyMode() throws Exception { + Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), + Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY); + Thread.sleep(TIMEOUT); + verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY); + } + + @MediumTest + public void testLocationSettingsElements() throws Exception { + String[] textElements = {"Location", "Mode", "Recent location requests", + "Location services"}; + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_LOCATION_SOURCE_SETTINGS); + Thread.sleep(TIMEOUT); + for (String element : textElements) { + assertNotNull(element + " item not found under Location Settings", + mDevice.wait(Until.findObject(By.text(element)), TIMEOUT)); + } + } + + @MediumTest + public void testLocationSettingsOverflowMenuElements() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_LOCATION_SOURCE_SETTINGS); + // Verify help & feedback + assertNotNull("Help & feedback item not found under Location Settings", + mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT)); + // Verify scanning + assertNotNull("Scanning item not found under Location Settings", + mDevice.wait(Until.findObject(By.text("Scanning")), TIMEOUT)); + } + + private void verifyLocationSettingsMode(int mode) throws Exception { + int modeIntValue = 1; + String textMode = "Device only"; + if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) { + modeIntValue = 3; + textMode = "High accuracy"; + } + else if (mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) { + modeIntValue = 2; + textMode = "Battery saving"; + } + // Load location settings + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_LOCATION_SOURCE_SETTINGS); + // Tap on mode + dismissAlertDialogs(); + // Load location settings + mDevice.wait(Until.findObject(By.text("Mode")), TIMEOUT).click(); + Thread.sleep(TIMEOUT); + assertNotNull("Location mode screen not loaded", mDevice.wait(Until.findObject + (By.text("Location mode")), TIMEOUT)); + // Choose said mode + mDevice.wait(Until.findObject(By.text(textMode)), TIMEOUT).click(); + Thread.sleep(TIMEOUT); + dismissAlertDialogs(); + mDevice.wait(Until.findObject(By.desc("Navigate up")), TIMEOUT).click(); + Thread.sleep(TIMEOUT); + if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY || + mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) { + dismissAlertDialogs(); + } + // get setting and verify value + // Verify change of mode + int locationSettingMode = + Settings.Secure.getInt(getInstrumentation().getContext().getContentResolver(), + Settings.Secure.LOCATION_MODE); + assertEquals(mode + " value not set correctly for location.", modeIntValue, + locationSettingMode); + } + + private void verifyLocationSettingsOnOrOff(boolean verifyOn) throws Exception { + // Set location flag + if (verifyOn) { + Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), + Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); + } + else { + Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), + Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY); + } + dismissAlertDialogs(); + // Load location settings + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_LOCATION_SOURCE_SETTINGS); + dismissAlertDialogs(); + // Toggle UI + mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, "switch_widget")), TIMEOUT).click(); + dismissAlertDialogs(); + Thread.sleep(TIMEOUT); + // Verify change in setting + int locationEnabled = Settings.Secure.getInt(getInstrumentation() + .getContext().getContentResolver(), + Settings.Secure.LOCATION_MODE); + if (verifyOn) { + assertFalse("Location not enabled correctly", locationEnabled == 0); + } + else { + assertEquals("Location not disabled correctly", 0, locationEnabled); + } + } + + // This method dismisses both alert dialogs that might popup and + // interfere with the test. Since the order in which the dialog + // shows up changes in no specific known way, we're checking for + // both dialogs in any order for a robust test. Bug b/36233151 + // filed against Location team for specifications. This is a + // workaround in the meantime to ensure coverage. + private void dismissAlertDialogs() throws Exception { + for (int count = 0; count < 2; count++) { + UiObject2 agreeDialog = mDevice.wait(Until.findObject + (By.text("Improve location accuracy?")), TIMEOUT); + UiObject2 previousChoiceYesButton = mDevice.wait(Until.findObject + (By.text("YES")), TIMEOUT); + if (agreeDialog != null) { + mDevice.wait(Until.findObject + (By.text("AGREE")), TIMEOUT).click(); + Thread.sleep(TIMEOUT); + assertNull("Improve location dialog not dismissed", + mDevice.wait(Until.findObject + (By.text("Improve location accuracy?")), TIMEOUT)); + } + if (previousChoiceYesButton != null) { + previousChoiceYesButton.click(); + // Short sleep to wait for the new screen + Thread.sleep(TIMEOUT); + } + } + } +} diff --git a/tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTests.java b/tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTests.java new file mode 100644 index 00000000000..25236869561 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTests.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; +import android.provider.Settings; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.system.helpers.SettingsHelper; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; + + +public class MoreWirelessSettingsTests extends InstrumentationTestCase { + + private static final String SETTINGS_PACKAGE = "com.android.settings"; + private static final int TIMEOUT = 2000; + private UiDevice mDevice; + + @Override + public void setUp() throws Exception { + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientaion", e); + } + } + + @Override + protected void tearDown() throws Exception { + mDevice.pressBack(); + mDevice.pressHome(); + super.tearDown(); + } + + @Presubmit + @MediumTest + public void testAirplaneModeEnabled() throws Exception { + verifyAirplaneModeOnOrOff(true); + // Toggling this via the wifi network settings page + // because of bug b/34858716. Once that is fixed, + // we should be able to set this via Settings putString. + toggleAirplaneModeSwitch(); + } + + @Presubmit + @MediumTest + public void testAirplaneModeDisabled() throws Exception { + verifyAirplaneModeOnOrOff(false); + } + + @MediumTest + public void testTetheringMenuLoad() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_WIRELESS_SETTINGS); + mDevice.wait(Until + .findObject(By.text("Hotspot & tethering")), TIMEOUT) + .click(); + Thread.sleep(TIMEOUT); + UiObject2 usbTethering = mDevice.wait(Until + .findObject(By.text("USB tethering")), TIMEOUT); + assertNotNull("Tethering screen did not load correctly", usbTethering); + } + + @MediumTest + public void testVPNMenuLoad() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_WIRELESS_SETTINGS); + mDevice.wait(Until + .findObject(By.text("VPN")), TIMEOUT) + .click(); + Thread.sleep(TIMEOUT); + UiObject2 usbTethering = mDevice.wait(Until + .findObject(By.res(SETTINGS_PACKAGE, "vpn_create")), TIMEOUT); + assertNotNull("VPN screen did not load correctly", usbTethering); + } + + private void verifyAirplaneModeOnOrOff(boolean verifyOn) throws Exception { + if (verifyOn) { + Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.AIRPLANE_MODE_ON, "0"); + } + else { + Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.AIRPLANE_MODE_ON, "1"); + } + toggleAirplaneModeSwitch(); + String airplaneModeValue = Settings.Global + .getString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.AIRPLANE_MODE_ON); + if (verifyOn) { + assertEquals("1", airplaneModeValue); + } + else { + assertEquals("0", airplaneModeValue); + } + } + + private void toggleAirplaneModeSwitch() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_WIRELESS_SETTINGS); + mDevice.wait(Until + .findObject(By.text("Airplane mode")), TIMEOUT) + .click(); + Thread.sleep(TIMEOUT); + } +} diff --git a/tests/uitests/src/com/android/settings/ui/NotificationSettingsTests.java b/tests/uitests/src/com/android/settings/ui/NotificationSettingsTests.java new file mode 100644 index 00000000000..133332c2dac --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/NotificationSettingsTests.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.content.Intent; +import android.os.RemoteException; +import android.provider.Settings; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.BySelector; +import android.support.test.uiautomator.Direction; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.system.helpers.ActivityHelper; +import android.system.helpers.SettingsHelper; +import android.widget.ListView; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.util.Log; + +/** Verifies that you can get to the notification app listing page from the apps & notifications + * page */ +public class NotificationSettingsTests extends InstrumentationTestCase { + private static final boolean LOCAL_LOGV = false; + private static final String TAG = "NotifiSettingsTests"; + private static final int TIMEOUT = 2000; + private ActivityHelper mActivityHelper = null; + private SettingsHelper mSettingsHelper = null; + + private UiDevice mDevice; + @Override + public void setUp() throws Exception { + if (LOCAL_LOGV) { + Log.d(TAG, "-------"); + } + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + mActivityHelper = ActivityHelper.getInstance(); + mSettingsHelper = SettingsHelper.getInstance(); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("Failed to freeze device orientaion", e); + } + + // make sure we are in a clean state before starting the test + mDevice.pressHome(); + Thread.sleep(TIMEOUT * 2); + launchAppsSettings(); + } + + @Override + protected void tearDown() throws Exception { + mDevice.pressBack(); + mDevice.pressHome(); // finish settings activity + mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating + super.tearDown(); + } + + @MediumTest + public void testNotificationsSettingsListForCalculator() { + UiObject2 configureNotifications = mDevice.wait( + Until.findObject(By.text("Notifications")), TIMEOUT); + configureNotifications.click(); + mDevice.wait(Until.findObject(By.text("Blink light")), TIMEOUT); + UiObject2 appNotifications = mDevice.wait( + Until.findObject(By.text("On for all apps")), TIMEOUT); + appNotifications.click(); + UiObject2 view = + mDevice.wait( + Until.findObject(By.text("All apps")), TIMEOUT); + assertNotNull("Could not find Settings > Apps screen", view); + UiObject2 app = mDevice.wait(Until.findObject(By.text("Calculator")), TIMEOUT); + assertNotNull("Could not find Calculator notification settings", app); + } + + + @MediumTest + public void testNotificationsSettingsListForPhone() { + UiObject2 configureNotifications = mDevice.wait( + Until.findObject(By.text("Notifications")), TIMEOUT); + configureNotifications.click(); + mDevice.wait(Until.findObject(By.text("Blink light")), TIMEOUT); + UiObject2 appNotifications = mDevice.wait( + Until.findObject(By.text("On for all apps")), TIMEOUT); + appNotifications.click(); + UiObject2 view = + mDevice.wait( + Until.findObject(By.text("All apps")), TIMEOUT); + assertNotNull("Could not find Settings > Apps screen", view); + + final BySelector preferenceListSelector = By.clazz(ListView.class).res("android:id/list"); + UiObject2 apps = mDevice.wait(Until.findObject(preferenceListSelector), TIMEOUT); + + UiObject2 phone = scrollTo(mDevice, apps, By.text("Phone"), Direction.DOWN); + assertNotNull("Could not find Phone notification settings", phone); + phone.click(); + UiObject2 incomingCalls = mDevice.wait(Until.findObject(By.text("Incoming calls")), TIMEOUT); + assertNotNull("Could not find incoming calls channel", incomingCalls); + incomingCalls.click(); + + // here's the meat of this test: make sure that you cannot change + // most settings for this channel + + UiObject2 importance = mDevice.wait(Until.findObject(By.text("Importance")), TIMEOUT); + assertNotNull("Could not find importance toggle", importance); + assertFalse(importance.isEnabled()); + assertFalse(mDevice.wait(Until.findObject(By.text("Sound")), TIMEOUT).isEnabled());; + assertFalse(mDevice.wait(Until.findObject(By.text("Vibrate")), TIMEOUT).isEnabled()); + assertFalse(mDevice.wait(Until.findObject(By.text("Override Do Not Disturb")), TIMEOUT).isEnabled()); + + + + + + + } + + private UiObject2 scrollTo(UiDevice device, UiObject2 scrollable, + BySelector target, Direction direction) { + while (!device.hasObject(target) && scrollable.scroll(direction, 1.0f)) { + // continue + } + if (!device.hasObject(target)) { + // Scroll once more if not found; in some cases UiObject2.scroll can return false when + // the last item is not fully visible yet for list views. + scrollable.scroll(direction, 1.0f); + } + return device.findObject(target); + } + + + private void launchAppsSettings() throws Exception { + Intent appsSettingsIntent = new Intent(Settings.ACTION_SETTINGS); + mActivityHelper.launchIntent(appsSettingsIntent); + mSettingsHelper.flingSettingsToStart(); + UiObject2 view = mDevice.wait( + Until.findObject(By.text("Apps & notifications")), TIMEOUT); + view.click(); + UiObject2 title = mDevice.wait( + Until.findObject(By.text("Apps & notifications")), TIMEOUT); + assertNotNull("Could not find Settings > Apps & notifications screen", title); + } +} diff --git a/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java b/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java new file mode 100644 index 00000000000..b730690d22c --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.os.RemoteException; +import android.provider.Settings; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.system.helpers.SettingsHelper; + +import com.android.settings.ui.testutils.SettingsTestUtils; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@MediumTest +@RunWith(AndroidJUnit4.class) +public class SecuritySettingsLaunchTest { + + // Items we really want to always show + private static final String[] CATEGORIES = new String[]{ + "Security status", + "Device security", + "Privacy", + }; + + private UiDevice mDevice; + private SettingsHelper mHelper; + + @Before + public void setUp() throws Exception { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + mHelper = SettingsHelper.getInstance(); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientaion", e); + } + } + + @After + public void tearDown() throws Exception { + // Go back to home for next test. + mDevice.pressHome(); + } + + @Test + public void launchSecuritySettings() throws Exception { + // Launch Settings + SettingsHelper.launchSettingsPage( + InstrumentationRegistry.getContext(), Settings.ACTION_SECURITY_SETTINGS); + mHelper.scrollVert(false); + for (String category : CATEGORIES) { + SettingsTestUtils.assertTitleMatch(mDevice, category); + } + } +} diff --git a/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java b/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java new file mode 100644 index 00000000000..0aec505185e --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.app.NotificationManager; +import android.content.ContentResolver; +import android.content.Context; +import android.os.Handler; +import android.os.SystemClock; +import android.provider.Settings; +import android.service.notification.ZenModeConfig; +import android.support.test.uiautomator.UiObject2; +import android.system.helpers.SettingsHelper; +import android.system.helpers.SettingsHelper.SettingsType; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.Until; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.Suppress; + +import java.util.HashMap; + +public class SoundSettingsTest extends InstrumentationTestCase { + private static final String PAGE = Settings.ACTION_SOUND_SETTINGS; + private static final int TIMEOUT = 2000; + + private UiDevice mDevice; + private ContentResolver mResolver; + private SettingsHelper mHelper; + + + private HashMap ringtoneSounds = new HashMap() {{ + put("angler","Dione"); + put("bullhead","Dione"); + put("marlin","Spaceship"); + put("sailfish","Spaceship"); + put("walleye","Copycat"); + put("taimen","Copycat"); + }}; + + private HashMap ringtoneCodes = new HashMap() {{ + put("angler","38"); + put("bullhead","38"); + put("marlin","37"); + put("sailfish","37"); + put("walleye","26"); + put("taimen","26"); + }}; + + private HashMap alarmSounds = new HashMap() {{ + put("angler","Awaken"); + put("bullhead","Awaken"); + put("marlin","Bounce"); + put("sailfish","Bounce"); + put("walleye","Cuckoo clock"); + put("taimen","Cuckoo clock"); + }}; + + private HashMap alarmCodes = new HashMap() {{ + put("angler","6"); + put("bullhead","6"); + put("marlin","49"); + put("sailfish","49"); + put("walleye","15"); + put("taimen","15"); + }}; + + private HashMap notificationSounds = new HashMap() {{ + put("angler","Ceres"); + put("bullhead","Ceres"); + put("marlin","Trill"); + put("sailfish","Trill"); + put("walleye","Pipes"); + put("taimen","Pipes"); + }}; + + + private HashMap notificationCodes = new HashMap() {{ + put("angler","26"); + put("bullhead","26"); + put("marlin","57"); + put("sailfish","57"); + put("walleye","69"); + put("taimen","69"); + }}; + + @Override + public void setUp() throws Exception { + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + mDevice.setOrientationNatural(); + mResolver = getInstrumentation().getContext().getContentResolver(); + mHelper = new SettingsHelper(); + } + + @Override + public void tearDown() throws Exception { + mDevice.pressBack(); + mDevice.pressHome(); + mDevice.waitForIdle(); + mDevice.unfreezeRotation(); + super.tearDown(); + } + + @MediumTest + public void testCallVibrate() throws Exception { + assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, + "Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING)); + assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, + "Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING)); + } + + @MediumTest + public void testOtherSoundsDialPadTones() throws Exception { + loadOtherSoundsPage(); + assertTrue("Dial pad tones not toggled", mHelper.verifyToggleSetting( + SettingsType.SYSTEM, PAGE, "Dial pad tones", + Settings.System.DTMF_TONE_WHEN_DIALING)); + } + + @MediumTest + public void testOtherSoundsScreenLocking() throws Exception { + loadOtherSoundsPage(); + assertTrue("Screen locking sounds not toggled", + mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, + "Screen locking sounds", Settings.System.LOCKSCREEN_SOUNDS_ENABLED)); + } + + @MediumTest + public void testOtherSoundsCharging() throws Exception { + loadOtherSoundsPage(); + assertTrue("Charging sounds not toggled", + mHelper.verifyToggleSetting(SettingsType.GLOBAL, PAGE, + "Charging sounds", Settings.Global.CHARGING_SOUNDS_ENABLED)); + } + + @MediumTest + public void testOtherSoundsTouch() throws Exception { + loadOtherSoundsPage(); + assertTrue("Touch sounds not toggled", + mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, + "Touch sounds", Settings.System.SOUND_EFFECTS_ENABLED)); + } + + @MediumTest + public void testOtherSoundsVibrateOnTap() throws Exception { + loadOtherSoundsPage(); + assertTrue("Vibrate on tap not toggled", + mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, + "Vibrate on tap", Settings.System.HAPTIC_FEEDBACK_ENABLED)); + } + + private void loadOtherSoundsPage() throws Exception { + launchSoundSettings(); + mHelper.scrollVert(false); + Thread.sleep(1000); + } + + private void launchSoundSettings() throws Exception { + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); + mHelper.scrollVert(false); + clickMore(); + Thread.sleep(1000); + mHelper.scrollVert(true); + Thread.sleep(1000); + } + + /* + * Rather than verifying every ringtone, verify the ones least likely to change + * (None and Hangouts) and an arbitrary one from the ringtone pool. + */ + @MediumTest + public void testPhoneRingtoneNone() throws Exception { + launchSoundSettings(); + mHelper.clickSetting("Phone ringtone"); + verifyRingtone(new RingtoneSetting("None", "null"), + Settings.System.RINGTONE); + } + + @MediumTest + @Suppress + public void testPhoneRingtoneHangouts() throws Exception { + launchSoundSettings(); + mHelper.clickSetting("Phone ringtone"); + verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE); + } + + @MediumTest + public void testPhoneRingtone() throws Exception { + launchSoundSettings(); + mHelper.clickSetting("Phone ringtone"); + String ringtone = ringtoneSounds.get(mDevice.getProductName()).toString(); + String ringtoneSettingValue = ringtoneCodes.get(mDevice.getProductName()).toString(); + verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue), + Settings.System.RINGTONE); + } + + @MediumTest + public void testNotificationRingtoneNone() throws Exception { + launchSoundSettings(); + mHelper.clickSetting("Default notification sound"); + verifyRingtone(new RingtoneSetting("None", "null"), + Settings.System.NOTIFICATION_SOUND); + } + + @MediumTest + @Suppress + public void testNotificationRingtoneHangouts() throws Exception { + launchSoundSettings(); + mHelper.clickSetting("Default notification sound"); + verifyRingtone(new RingtoneSetting("Hangouts Message", "30"), + Settings.System.NOTIFICATION_SOUND); + } + + @MediumTest + public void testNotificationRingtone() throws Exception { + launchSoundSettings(); + mHelper.clickSetting("Default notification sound"); + String notificationRingtone = notificationSounds.get(mDevice.getProductName()).toString(); + String notificationSettingValue = notificationCodes.get(mDevice.getProductName()).toString(); + verifyRingtone(new RingtoneSetting(notificationRingtone, notificationSettingValue), + Settings.System.NOTIFICATION_SOUND); + } + + @MediumTest + public void testAlarmRingtoneNone() throws Exception { + launchSoundSettings(); + mHelper.clickSetting("Default alarm sound"); + verifyRingtone(new RingtoneSetting("None", "null"), + Settings.System.ALARM_ALERT); + } + + @MediumTest + public void testAlarmRingtone() throws Exception { + launchSoundSettings(); + String alarmRingtone = alarmSounds.get(mDevice.getProductName()).toString(); + String alarmSettingValue = alarmCodes.get(mDevice.getProductName()).toString(); + mHelper.clickSetting("Default alarm sound"); + verifyRingtone(new RingtoneSetting(alarmRingtone, alarmSettingValue), + Settings.System.ALARM_ALERT); + } + + /* + * This method verifies that setting a custom ringtone changes the + * ringtone code setting on the system. Each ringtone sound corresponds + * to an arbitrary code. To see which ringtone code this is on your device, run + * adb shell settings get system ringtone + * The number you see at the end of the file path is the one you need. + * To see alarms and notifications ringtone codes, run the following: + * adb shell settings get system alarm_alert + * adb shell settings get system notification_sound + * @param r Ringtone setting - the name of the ringtone as displayed on device + * @param settingName - the code of the ringtone as explained above + * @param dir - the direction in which to scroll + */ + private void verifyRingtone(RingtoneSetting r, String settingName) throws Exception { + findRingtoneInList(r.getName()).click(); + if (mDevice.getProductName().equals("walleye") || mDevice.getProductName().equals("taimen")) { + mDevice.wait(Until.findObject(By.text("SAVE")), TIMEOUT).click(); + } + else { + mDevice.wait(Until.findObject(By.text("OK")), TIMEOUT).click(); + } + SystemClock.sleep(1000); + if (r.getVal().equals("null")) { + assertEquals(null, + Settings.System.getString(mResolver, settingName)); + } else if (r.getName().contains("Hangouts")) { + assertEquals("content://media/external/audio/media/" + r.getVal(), + Settings.System.getString(mResolver, settingName)); + } else { + assertEquals("content://media/internal/audio/media/" + r.getVal(), + Settings.System.getString(mResolver, settingName)); + } + } + + private enum ScrollDir { + UP, + DOWN, + NOSCROLL + } + + class RingtoneSetting { + private final String mName; + private final String mMediaVal; + public RingtoneSetting(String name, String fname) { + mName = name; + mMediaVal = fname; + } + public String getName() { + return mName; + } + public String getVal() { + return mMediaVal; + } + } + + private void clickMore() throws InterruptedException { + UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT); + if (more != null) { + more.click(); + Thread.sleep(TIMEOUT); + } + } + + private UiObject2 findRingtoneInList(String ringtone) throws Exception { + mHelper.scrollVert(false); + SystemClock.sleep(1000); + UiObject2 ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT); + int count = 0; + while (ringToneObject == null && count < 5) { + mHelper.scrollVert(true); + SystemClock.sleep(1000); + ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT); + count++; + } + return ringToneObject; + } +} diff --git a/tests/uitests/src/com/android/settings/ui/SyncSettingsTest.java b/tests/uitests/src/com/android/settings/ui/SyncSettingsTest.java new file mode 100644 index 00000000000..3dca424b2bd --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/SyncSettingsTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.os.RemoteException; +import android.provider.Settings; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.system.helpers.SettingsHelper; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static junit.framework.Assert.assertTrue; + +@MediumTest +@RunWith(AndroidJUnit4.class) +public class SyncSettingsTest { + private static final int TIMEOUT = 2000; + + private UiDevice mDevice; + + @Before + public void setUp() throws Exception { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientaion", e); + } + } + + @After + public void tearDown() throws Exception { + // Need to finish settings activity + mDevice.pressHome(); + } + + @Test + public void syncPageShouldHaveAddAccountButton() throws Exception { + // Launch Settings + SettingsHelper.launchSettingsPage( + InstrumentationRegistry.getContext(), Settings.ACTION_SYNC_SETTINGS); + UiObject2 addAccount = mDevice.wait( + Until.findObject(By.text("Add account")), TIMEOUT); + assertTrue(addAccount != null); + } +} diff --git a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java new file mode 100644 index 00000000000..1e3b978c804 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java @@ -0,0 +1,777 @@ +/* + * Copyright (C) 2018 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.ui; + +import android.content.Context; +import android.content.Intent; +import android.net.wifi.WifiManager; +import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; +import android.provider.Settings; +import android.system.helpers.CommandsHelper; +import android.system.helpers.SettingsHelper; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.BySelector; +import android.support.test.uiautomator.Direction; +import android.support.test.uiautomator.StaleObjectException; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.Suppress; +import android.util.Log; +import junit.framework.AssertionFailedError; + +public class WirelessNetworkSettingsTests extends InstrumentationTestCase { + // These back button presses are performed in tearDown() to exit Wifi + // Settings sub-menus that a test might finish in. This number should be + // high enough to account for the deepest sub-menu a test might enter. + private static final int NUM_BACK_BUTTON_PRESSES = 5; + private static final int TIMEOUT = 2000; + private static final int SLEEP_TIME = 500; + private static final String AIRPLANE_MODE_BROADCAST = + "am broadcast -a android.intent.action.AIRPLANE_MODE"; + private static final String TAG="WirelessNetworkSettingsTests"; + + // Note: The values of these variables might affect flakiness in tests that involve + // scrolling. Adjust where necessary. + private static final float SCROLL_UP_PERCENT = 10.0f; + private static final float SCROLL_DOWN_PERCENT = 0.5f; + private static final int MAX_SCROLL_ATTEMPTS = 10; + private static final int MAX_ADD_NETWORK_BUTTON_ATTEMPTS = 3; + private static final int SCROLL_SPEED = 2000; + + private static final String TEST_SSID = "testSsid"; + private static final String TEST_PW_GE_8_CHAR = "testPasswordGreaterThan8Char"; + private static final String TEST_PW_LT_8_CHAR = "lt8Char"; + private static final String TEST_DOMAIN = "testDomain.com"; + + private static final String SETTINGS_PACKAGE = "com.android.settings"; + + private static final String CHECKBOX_CLASS = "android.widget.CheckBox"; + private static final String SPINNER_CLASS = "android.widget.Spinner"; + private static final String EDIT_TEXT_CLASS = "android.widget.EditText"; + private static final String SCROLLVIEW_CLASS = "android.widget.ScrollView"; + private static final String LISTVIEW_CLASS = "android.widget.ListView"; + + private static final String ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT = "CANCEL"; + private static final String ADD_NETWORK_MENU_SAVE_BUTTON_TEXT = "SAVE"; + private static final String ADD_NETWORK_PREFERENCE_TEXT = "Add network"; + private static final String CONFIGURE_WIFI_PREFERENCE_TEXT = "Wi‑Fi preferences"; + private static final String CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT = "Advanced"; + private static final String CACERT_MENU_PLEASE_SELECT_TEXT = "Please select"; + private static final String CACERT_MENU_USE_SYSTEM_CERTS_TEXT = "Use system certificates"; + private static final String CACERT_MENU_DO_NOT_VALIDATE_TEXT = "Do not validate"; + private static final String USERCERT_MENU_PLEASE_SELECT_TEXT = "Please select"; + private static final String USERCERT_MENU_DO_NOT_PROVIDE_TEXT = "Do not provide"; + private static final String SECURITY_OPTION_NONE_TEXT = "None"; + private static final String SECURITY_OPTION_WEP_TEXT = "WEP"; + private static final String SECURITY_OPTION_PSK_TEXT = "WPA/WPA2 PSK"; + private static final String SECURITY_OPTION_EAP_TEXT = "802.1x EAP"; + private static final String EAP_METHOD_PEAP_TEXT = "PEAP"; + private static final String EAP_METHOD_TLS_TEXT = "TLS"; + private static final String EAP_METHOD_TTLS_TEXT = "TTLS"; + private static final String EAP_METHOD_PWD_TEXT = "PWD"; + private static final String EAP_METHOD_SIM_TEXT = "SIM"; + private static final String EAP_METHOD_AKA_TEXT = "AKA"; + private static final String EAP_METHOD_AKA_PRIME_TEXT = "AKA'"; + private static final String PHASE2_MENU_NONE_TEXT = "None"; + private static final String PHASE2_MENU_MSCHAPV2_TEXT = "MSCHAPV2"; + private static final String PHASE2_MENU_GTC_TEXT = "GTC"; + + private static final String ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID = "wifi_advanced_togglebox"; + private static final String ADD_NETWORK_MENU_IP_SETTINGS_RES_ID = "ip_settings"; + private static final String ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID = "proxy_settings"; + private static final String ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID = "security"; + private static final String ADD_NETWORK_MENU_EAP_METHOD_RES_ID = "method"; + private static final String ADD_NETWORK_MENU_SSID_RES_ID = "ssid"; + private static final String ADD_NETWORK_MENU_PHASE2_RES_ID = "phase2"; + private static final String ADD_NETWORK_MENU_CACERT_RES_ID = "ca_cert"; + private static final String ADD_NETWORK_MENU_USERCERT_RES_ID = "user_cert"; + private static final String ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID = "no_domain_warning"; + private static final String ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID = "no_ca_cert_warning"; + private static final String ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID = "l_domain"; + private static final String ADD_NETWORK_MENU_DOMAIN_RES_ID = "domain"; + private static final String ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID = "l_identity"; + private static final String ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID = "l_anonymous"; + private static final String ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID = "password_layout"; + private static final String ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID = + "show_password_layout"; + private static final String ADD_NETWORK_MENU_PASSWORD_RES_ID = "password"; + + private static final BySelector ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR = + By.scrollable(true).clazz(SCROLLVIEW_CLASS); + private static final BySelector SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR = + By.scrollable(true).clazz(LISTVIEW_CLASS); + + private UiDevice mDevice; + private CommandsHelper mCommandsHelper; + + @Override + public void setUp() throws Exception { + super.setUp(); + mDevice = UiDevice.getInstance(getInstrumentation()); + try { + mDevice.setOrientationNatural(); + } catch (RemoteException e) { + throw new RuntimeException("failed to freeze device orientation", e); + } + // Ensure airplane mode is OFF so that wifi can be enabled using WiFiManager. + Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.AIRPLANE_MODE_ON, "0"); + Log.d(TAG, "sending airplane mode broadcast to device"); + mCommandsHelper = CommandsHelper.getInstance(); + mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST); + } + + @Override + protected void tearDown() throws Exception { + // Exit all settings sub-menus. + for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) { + mDevice.pressBack(); + } + mDevice.pressHome(); + super.tearDown(); + } + + @Presubmit + @MediumTest + public void testWiFiEnabled() throws Exception { + verifyWiFiOnOrOff(true); + } + + @Presubmit + @MediumTest + public void testWiFiDisabled() throws Exception { + verifyWiFiOnOrOff(false); + } + + @MediumTest + public void testWifiMenuLoadConfigure() throws Exception { + loadWiFiConfigureMenu(); + Thread.sleep(SLEEP_TIME); + UiObject2 configureWiFiHeading = mDevice.wait(Until.findObject + (By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT); + assertNotNull("Configure WiFi menu has not loaded correctly", configureWiFiHeading); + } + + @MediumTest + public void testNetworkNotificationsOn() throws Exception { + verifyNetworkNotificationsOnOrOff(true); + } + + @MediumTest + public void testNetworkNotificationsOff() throws Exception { + verifyNetworkNotificationsOnOrOff(false); + } + + @MediumTest + public void testAddNetworkMenu_Default() throws Exception { + loadAddNetworkMenu(); + + // Submit button should be disabled by default, while cancel button should be enabled. + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + assertTrue(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + // Check that the SSID field is defaults to the hint. + assertEquals("Enter the SSID", mDevice.wait(Until.findObject(By + .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID) + .clazz(EDIT_TEXT_CLASS)), TIMEOUT*2) + .getText()); + + // Check Security defaults to None. + assertEquals("None", mDevice.wait(Until.findObject(By + .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID) + .clazz(SPINNER_CLASS)), TIMEOUT) + .getChildren().get(0).getText()); + + // Check advanced options are collapsed by default. + assertFalse(mDevice.wait(Until.findObject(By + .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID) + .clazz(CHECKBOX_CLASS)), TIMEOUT).isChecked()); + + } + + @Suppress + @MediumTest + public void testAddNetworkMenu_Proxy() throws Exception { + loadAddNetworkMenu(); + + // Toggle advanced options. + mDevice.wait(Until.findObject(By + .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID) + .clazz(CHECKBOX_CLASS)), TIMEOUT).click(); + + // Verify Proxy defaults to None. + BySelector proxySettingsBySelector = + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID) + .clazz(SPINNER_CLASS); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector); + assertEquals("None", mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT) + .getChildren().get(0).getText()); + + // Verify that Proxy Manual fields appear. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector); + mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click(); + mDevice.wait(Until.findObject(By.text("Manual")), TIMEOUT).click(); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, "proxy_warning_limited_support")); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, "proxy_hostname")); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, "proxy_exclusionlist")); + + // Verify that Proxy Auto-Config options appear. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector); + mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click(); + mDevice.wait(Until.findObject(By.text("Proxy Auto-Config")), TIMEOUT).click(); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, "proxy_pac")); + } + + @Suppress + @MediumTest + public void testAddNetworkMenu_IpSettings() throws Exception { + loadAddNetworkMenu(); + + // Toggle advanced options. + mDevice.wait(Until.findObject(By + .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID) + .clazz(CHECKBOX_CLASS)), TIMEOUT).click(); + + // Verify IP settings defaults to DHCP. + BySelector ipSettingsBySelector = + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IP_SETTINGS_RES_ID).clazz(SPINNER_CLASS); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector); + assertEquals("DHCP", mDevice.wait(Until.findObject(ipSettingsBySelector), TIMEOUT) + .getChildren().get(0).getText()); + + // Verify that Static IP settings options appear. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector).click(); + mDevice.wait(Until.findObject(By.text("Static")), TIMEOUT).click(); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, "ipaddress")); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, "gateway")); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, "network_prefix_length")); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, "dns1")); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, "dns2")); + } + + @Suppress + @MediumTest + public void testPhase2Settings() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_EAP_TEXT); + + BySelector phase2SettingsBySelector = + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID).clazz(SPINNER_CLASS); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, phase2SettingsBySelector); + assertEquals(PHASE2_MENU_NONE_TEXT, mDevice.wait(Until + .findObject(phase2SettingsBySelector), TIMEOUT).getChildren().get(0).getText()); + mDevice.wait(Until.findObject(phase2SettingsBySelector), TIMEOUT).click(); + Thread.sleep(SLEEP_TIME); + + // Verify Phase 2 authentication spinner options. + assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_NONE_TEXT)), TIMEOUT)); + assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_MSCHAPV2_TEXT)), TIMEOUT)); + assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_GTC_TEXT)), TIMEOUT)); + } + + @Suppress + @MediumTest + public void testCaCertSettings() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_EAP_TEXT); + + BySelector caCertSettingsBySelector = + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, caCertSettingsBySelector); + assertEquals(CACERT_MENU_PLEASE_SELECT_TEXT, mDevice.wait(Until + .findObject(caCertSettingsBySelector), TIMEOUT).getChildren().get(0).getText()); + mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click(); + Thread.sleep(SLEEP_TIME); + + // Verify CA certificate spinner options. + assertNotNull(mDevice.wait(Until.findObject( + By.text(CACERT_MENU_PLEASE_SELECT_TEXT)), TIMEOUT)); + assertNotNull(mDevice.wait(Until.findObject( + By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT)); + assertNotNull(mDevice.wait(Until.findObject( + By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT)); + + // Verify that a domain field and warning appear when the user selects the + // "Use system certificates" option. + mDevice.wait(Until.findObject(By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT).click(); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID)); + + // Verify that a warning appears when the user chooses the "Do Not Validate" option. + mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click(); + mDevice.wait(Until.findObject(By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT).click(); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID)); + } + + @Suppress + @MediumTest + public void testAddNetwork_NoSecurity() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_NONE_TEXT); + + // Entering an SSID is enough to enable the submit button. // TODO THIS GUY + enterSSID(TEST_SSID); + assertTrue(mDevice.wait(Until + .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + } + + @Suppress + @MediumTest + public void testAddNetwork_WEP() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_WEP_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + // Verify that WEP fields appear. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID)); + + // Entering an SSID alone does not enable the submit button. + enterSSID(TEST_SSID); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + // Submit button is only enabled after a password is entered. + enterPassword(TEST_PW_GE_8_CHAR); + assertTrue(mDevice.wait(Until + .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + } + + @Suppress + @MediumTest + public void testAddNetwork_PSK() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_PSK_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + // Verify that PSK fields appear. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID)); + + // Entering an SSID alone does not enable the submit button. + enterSSID(TEST_SSID); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + // Entering an password that is too short does not enable submit button. + enterPassword(TEST_PW_LT_8_CHAR); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + // Submit button is only enabled after a password of valid length is entered. + enterPassword(TEST_PW_GE_8_CHAR); + assertTrue(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + } + + @Suppress + @MediumTest + public void testAddNetwork_EAP_PEAP() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_EAP_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + selectEAPMethod(EAP_METHOD_PEAP_TEXT); + + // Verify that EAP-PEAP fields appear. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID)); + + // Entering an SSID alone does not enable the submit button. + enterSSID(TEST_SSID); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + verifyCaCertificateSubmitConditions(); + } + + @Suppress + @MediumTest + public void testAddNetwork_EAP_TLS() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_EAP_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + selectEAPMethod(EAP_METHOD_TLS_TEXT); + + // Verify that EAP-TLS fields appear. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); + + // Entering an SSID alone does not enable the submit button. + enterSSID(TEST_SSID); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + // Selecting the User certificate "Do not provide" option alone does not enable the submit + // button. + selectUserCertificateOption(USERCERT_MENU_DO_NOT_PROVIDE_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + verifyCaCertificateSubmitConditions(); + } + + @Suppress + @MediumTest + public void testAddNetwork_EAP_TTLS() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_EAP_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + selectEAPMethod(EAP_METHOD_TTLS_TEXT); + + // Verify that EAP-TLS fields appear. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); + + // Entering an SSID alone does not enable the submit button. + enterSSID(TEST_SSID); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + verifyCaCertificateSubmitConditions(); + } + + @Suppress + @MediumTest + public void testAddNetwork_EAP_PWD() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_EAP_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + selectEAPMethod(EAP_METHOD_PWD_TEXT); + + // Verify that EAP-TLS fields appear. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); + + // Entering an SSID alone enables the submit button. + enterSSID(TEST_SSID); + assertTrue(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + } + + @Suppress + @MediumTest + public void testAddNetwork_EAP_SIM() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_EAP_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + selectEAPMethod(EAP_METHOD_SIM_TEXT); + + // Entering an SSID alone enables the submit button. + enterSSID(TEST_SSID); + assertTrue(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + } + + @Suppress + @MediumTest + public void testAddNetwork_EAP_AKA() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_EAP_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + selectEAPMethod(EAP_METHOD_AKA_TEXT); + + // Entering an SSID alone enables the submit button. + enterSSID(TEST_SSID); + assertTrue(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + } + + @Suppress + @MediumTest + public void testAddNetwork_EAP_AKA_PRIME() throws Exception { + loadAddNetworkMenu(); + selectSecurityOption(SECURITY_OPTION_EAP_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + selectEAPMethod(EAP_METHOD_AKA_PRIME_TEXT); + + // Entering an SSID alone enables the submit button. + enterSSID(TEST_SSID); + assertTrue(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + } + + private void verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue) + throws Exception { + loadWiFiConfigureMenu(); + mDevice.wait(Until.findObject(By.text("Keep Wi‑Fi on during sleep")), TIMEOUT) + .click(); + mDevice.wait(Until.findObject(By.clazz("android.widget.CheckedTextView") + .text(settingToBeVerified)), TIMEOUT).click(); + Thread.sleep(SLEEP_TIME); + int keepWiFiOnSetting = + Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(), + Settings.Global.WIFI_SLEEP_POLICY); + assertEquals(settingValue, keepWiFiOnSetting); + } + + private void verifyNetworkNotificationsOnOrOff(boolean verifyOn) + throws Exception { + // Enable network recommendations to enable the toggle switch for Network + // notifications + Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, "1"); + if (verifyOn) { + Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "0"); + } + else { + Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1"); + } + loadWiFiConfigureMenu(); + mDevice.wait(Until.findObject(By.text("Open network notification")), TIMEOUT) + .click(); + Thread.sleep(SLEEP_TIME); + String wifiNotificationValue = + Settings.Global.getString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON); + if (verifyOn) { + assertEquals("1", wifiNotificationValue); + } + else { + assertEquals("0", wifiNotificationValue); + } + } + + private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception { + String switchText = "On"; + if (verifyOn) { + switchText = "Off"; + } + loadWiFiSettingsPage(!verifyOn); + mDevice.wait(Until + .findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT) + .click(); + Thread.sleep(SLEEP_TIME); + String wifiValue = + Settings.Global.getString(getInstrumentation().getContext().getContentResolver(), + Settings.Global.WIFI_ON); + if (verifyOn) { + // 1 is Enabled, 2 is Enabled while airplane mode is ON. + assertTrue(wifiValue.equals("1") || wifiValue.equals("2")); + } + else { + assertEquals("0", wifiValue); + } + } + + private void verifyCaCertificateSubmitConditions() throws Exception { + // Selecting the CA certificate "Do not validate" option enables the submit button. + selectCaCertificateOption(CACERT_MENU_DO_NOT_VALIDATE_TEXT); + assertTrue(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + // However, selecting the CA certificate "Use system certificates option" is not enough to + // enable the submit button. + selectCaCertificateOption(CACERT_MENU_USE_SYSTEM_CERTS_TEXT); + assertFalse(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + + // Submit button is only enabled after a domain is entered as well. + enterDomain(TEST_DOMAIN); + assertTrue(mDevice.wait(Until.findObject( + By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); + } + + private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception { + WifiManager wifiManager = (WifiManager)getInstrumentation().getContext() + .getSystemService(Context.WIFI_SERVICE); + wifiManager.setWifiEnabled(wifiEnabled); + SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), + Settings.ACTION_WIFI_SETTINGS); + } + + private void loadWiFiConfigureMenu() throws Exception { + loadWiFiSettingsPage(false); + Thread.sleep(TIMEOUT); + mDevice.wait(Until.findObject(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT).click(); + mDevice.wait(Until.findObject( + By.text(CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT)), TIMEOUT).click(); + } + + private void loadAddNetworkMenu() throws Exception { + loadWiFiSettingsPage(true); + for (int attempts = 0; attempts < MAX_ADD_NETWORK_BUTTON_ATTEMPTS; ++attempts) { + try { + findOrScrollToObject(By.scrollable(true), By.text(ADD_NETWORK_PREFERENCE_TEXT)) + .click(); + } catch (StaleObjectException e) { + // The network list might have been updated between when the Add network button was + // found, and when it UI automator attempted to click on it. Retry. + continue; + } + // If we get here, we successfully clicked on the Add network button, so we are done. + Thread.sleep(SLEEP_TIME*5); + return; + } + + fail("Failed to load Add Network Menu after " + MAX_ADD_NETWORK_BUTTON_ATTEMPTS + + " retries"); + } + + private void selectSecurityOption(String securityOption) throws Exception { + // We might not need to scroll to the security options if not enough add network menu + // options are visible. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID) + .clazz(SPINNER_CLASS)).click(); + Thread.sleep(SLEEP_TIME); + mDevice.wait(Until.findObject(By.text(securityOption)), TIMEOUT).click(); + } + + private void selectEAPMethod(String eapMethod) throws Exception { + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_EAP_METHOD_RES_ID).clazz(SPINNER_CLASS)) + .click(); + Thread.sleep(SLEEP_TIME); + findOrScrollToObject(SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR, By.text(eapMethod)).click(); + } + + private void selectUserCertificateOption(String userCertificateOption) throws Exception { + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID).clazz(SPINNER_CLASS)) + .click(); + mDevice.wait(Until.findObject(By.text(userCertificateOption)), TIMEOUT).click(); + } + + private void selectCaCertificateOption(String caCertificateOption) throws Exception { + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS)) + .click(); + mDevice.wait(Until.findObject(By.text(caCertificateOption)), TIMEOUT).click(); + } + + private void enterSSID(String ssid) throws Exception { + // We might not need to scroll to the SSID option if not enough add network menu options + // are visible. + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID).clazz(EDIT_TEXT_CLASS)) + .setText(ssid); + } + + private void enterPassword(String password) throws Exception { + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_RES_ID).clazz(EDIT_TEXT_CLASS)) + .setText(password); + } + + private void enterDomain(String domain) throws Exception { + findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, + By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_RES_ID)).setText(domain); + } + + // Use this if the UI object might or might not need to be scrolled to. + private UiObject2 findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector) + throws Exception { + UiObject2 object = mDevice.wait(Until.findObject(objectSelector), TIMEOUT); + if (object == null) { + object = scrollToObject(scrollableSelector, objectSelector); + } + return object; + } + + private UiObject2 scrollToObject(BySelector scrollableSelector, BySelector objectSelector) + throws Exception { + UiObject2 scrollable = mDevice.wait(Until.findObject(scrollableSelector), TIMEOUT); + if (scrollable == null) { + fail("Could not find scrollable UI object identified by " + scrollableSelector); + } + UiObject2 found = null; + // Scroll all the way up first, then all the way down. + while (true) { + // Optimization: terminate if we find the object while scrolling up to reset, so + // we save the time spent scrolling down again. + boolean canScrollAgain = scrollable.scroll(Direction.UP, SCROLL_UP_PERCENT, + SCROLL_SPEED); + found = mDevice.findObject(objectSelector); + if (found != null) return found; + if (!canScrollAgain) break; + } + for (int attempts = 0; found == null && attempts < MAX_SCROLL_ATTEMPTS; ++attempts) { + // Return value of UiObject2.scroll() is not reliable, so do not use it in loop + // condition, in case it causes this loop to terminate prematurely. + scrollable.scroll(Direction.DOWN, SCROLL_DOWN_PERCENT, SCROLL_SPEED); + found = mDevice.findObject(objectSelector); + } + if (found == null) { + fail("Could not scroll to UI object identified by " + objectSelector); + } + return found; + } +} diff --git a/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java b/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java new file mode 100644 index 00000000000..9b1be14bfa5 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2018 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.ui.testutils; + +import static org.junit.Assert.assertNotNull; + +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.Direction; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; + +public class SettingsTestUtils { + + public static final String SETTINGS_PACKAGE = "com.android.settings"; + public static final int TIMEOUT = 2000; + + private void scrollToTop(UiDevice device) throws Exception { + int count = 5; + UiObject2 view = null; + while (count >= 0) { + view = device.wait( + Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")), + TIMEOUT); + view.scroll(Direction.UP, 1.0f); + count--; + } + } + + public static void assertTitleMatch(UiDevice device, String title) { + int maxAttempt = 5; + UiObject2 item = null; + UiObject2 view = null; + while (maxAttempt-- > 0) { + item = device.wait(Until.findObject(By.res("android:id/title").text(title)), TIMEOUT); + if (item == null) { + view = device.wait( + Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")), + TIMEOUT); + view.scroll(Direction.DOWN, 1.0f); + } else { + return; + } + } + assertNotNull(String.format("%s in Setting has not been loaded correctly", title), item); + } +} From 754ca518422a2a633fc4d49436db7b15b4be0e84 Mon Sep 17 00:00:00 2001 From: yuemingw Date: Wed, 3 Jan 2018 18:09:31 +0000 Subject: [PATCH 07/30] Disable UI in Settings app when DISALLOW_CONFIG_LOCATION_MODE is set. Bug: 67674888 Test: m -j RunSettingsRoboTest Change-Id: I13a4fa4a3122bfd9b84f935c0aa83c019490eac9 --- .../settings/location/LocationEnabler.java | 9 ++++++++- .../location/LocationEnablerTest.java | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/location/LocationEnabler.java b/src/com/android/settings/location/LocationEnabler.java index 5c5399ceff9..4dcdac0c456 100644 --- a/src/com/android/settings/location/LocationEnabler.java +++ b/src/com/android/settings/location/LocationEnabler.java @@ -34,6 +34,7 @@ import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; import static com.android.settingslib.Utils.updateLocationMode; +import static com.android.settingslib.RestrictedLockUtils.checkIfRestrictionEnforced; /** * A class that listens to location settings change and modifies location settings @@ -140,8 +141,14 @@ public class LocationEnabler implements LifecycleObserver, OnResume, OnPause { } RestrictedLockUtils.EnforcedAdmin getShareLocationEnforcedAdmin(int userId) { - return RestrictedLockUtils.checkIfRestrictionEnforced( + RestrictedLockUtils.EnforcedAdmin admin = checkIfRestrictionEnforced( mContext, UserManager.DISALLOW_SHARE_LOCATION, userId); + + if (admin == null) { + admin = RestrictedLockUtils.checkIfRestrictionEnforced( + mContext, UserManager.DISALLOW_CONFIG_LOCATION_MODE, userId); + } + return admin; } boolean hasShareLocationRestriction(int userId) { diff --git a/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java index 462b926d383..f456f4109e5 100644 --- a/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java +++ b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java @@ -209,6 +209,23 @@ public class LocationEnablerTest { assertThat(mEnabler.isManagedProfileRestrictedByBase()).isTrue(); } + @Test + public void setRestriction_getShareLocationEnforcedAdmin_shouldReturnEnforcedAdmin() { + int userId = UserHandle.myUserId(); + List enforcingUsers = new ArrayList<>(); + // Add two enforcing users so that RestrictedLockUtils.checkIfRestrictionEnforced returns + // non-null. + enforcingUsers.add(new UserManager.EnforcingUser(userId, + UserManager.RESTRICTION_SOURCE_DEVICE_OWNER)); + enforcingUsers.add(new UserManager.EnforcingUser(userId, + UserManager.RESTRICTION_SOURCE_PROFILE_OWNER)); + when(mUserManager.getUserRestrictionSources( + UserManager.DISALLOW_CONFIG_LOCATION_MODE, UserHandle.of(userId))) + .thenReturn(enforcingUsers); + + assertThat(mEnabler.getShareLocationEnforcedAdmin(userId) != null).isTrue(); + } + private void mockManagedProfile() { final List userProfiles = new ArrayList<>(); final UserHandle userHandle = mock(UserHandle.class); @@ -223,4 +240,6 @@ public class LocationEnablerTest { private static ArgumentMatcher actionMatches(String expected) { return intent -> TextUtils.equals(expected, intent.getAction()); } + + } From 5cd49562765746b62028127960e041567a50d526 Mon Sep 17 00:00:00 2001 From: Andrew Sapperstein Date: Mon, 15 Jan 2018 13:46:41 -0800 Subject: [PATCH 08/30] Ignore first crash dialog. By default, no longer show the crash dialog the first time an app crashes. Instead, only multiple crashes will show by default. Add developer setting to control behavior, so app developers can ensure dialog always shows when a crash happens. Bug: 63703353, 70640329 Test: robotests, manual crashing with a test app Change-Id: I2e625ed147dafc188b28c52eb1b9cee6b2330d50 --- res/values/strings.xml | 5 + res/xml/development_settings.xml | 4 + .../DevelopmentSettingsDashboardFragment.java | 1 + ...wFirstCrashDialogPreferenceController.java | 94 ++++++++++++ ...stCrashDialogPreferenceControllerTest.java | 145 ++++++++++++++++++ 5 files changed, 249 insertions(+) create mode 100644 src/com/android/settings/development/ShowFirstCrashDialogPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/development/ShowFirstCrashDialogPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index cfefa55cc45..f42c0fc8bc4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9174,6 +9174,11 @@ Track all GNSS constellations and frequencies with no duty cycling + + Always show crash dialog + + Show dialog every time an app crashes + Storage access diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index aad5d2361b1..f6793411d5c 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -459,6 +459,10 @@ android:fragment="com.android.settings.applications.appops.BackgroundCheckSummary" android:title="@string/background_check_pref" /> + Date: Tue, 16 Jan 2018 15:51:57 -0800 Subject: [PATCH 09/30] Introduce boolean flags to show/hide items in Security & location. This adds 6 new boolean flags: config_show_manage_device_admin config_show_unlock_set_or_change config_show_screen_pinning_settings config_show_manage_trust_agents config_show_show_password config_show_trust_agent_click_intent Which when individually set to false, will hide the item from "Security & location". It will also hide them from surfacing in search results. Bug:62379222 Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.security Change-Id: I58d82cbc7f366a9666cdb0f7cd1b90ebbaf418f4 --- res/values/bools.xml | 18 ++++ ...ManageDeviceAdminPreferenceController.java | 2 +- .../ChangeScreenLockPreferenceController.java | 2 +- .../ScreenPinningPreferenceController.java | 3 +- .../ShowPasswordPreferenceController.java | 5 +- ...ManageTrustAgentsPreferenceController.java | 3 +- .../TrustAgentListPreferenceController.java | 2 +- tests/robotests/res/values-mcc999/config.xml | 6 ++ ...geDeviceAdminPreferenceControllerTest.java | 23 +++-- ...ngeScreenLockPreferenceControllerTest.java | 85 +++++++++++++++++++ ...ScreenPinningPreferenceControllerTest.java | 10 ++- .../ShowPasswordPreferenceControllerTest.java | 10 ++- ...geTrustAgentsPreferenceControllerTest.java | 10 ++- ...rustAgentListPreferenceControllerTest.java | 6 ++ 14 files changed, 168 insertions(+), 17 deletions(-) create mode 100644 tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java diff --git a/res/values/bools.xml b/res/values/bools.xml index 4469cc40521..e4a57ab1730 100644 --- a/res/values/bools.xml +++ b/res/values/bools.xml @@ -120,6 +120,24 @@ true + + true + + + true + + + true + + + true + + + true + + + true + true diff --git a/src/com/android/settings/enterprise/ManageDeviceAdminPreferenceController.java b/src/com/android/settings/enterprise/ManageDeviceAdminPreferenceController.java index 6f35641e721..7cfe7a9eb45 100644 --- a/src/com/android/settings/enterprise/ManageDeviceAdminPreferenceController.java +++ b/src/com/android/settings/enterprise/ManageDeviceAdminPreferenceController.java @@ -45,7 +45,7 @@ public class ManageDeviceAdminPreferenceController extends AbstractPreferenceCon @Override public boolean isAvailable() { - return true; + return mContext.getResources().getBoolean(R.bool.config_show_manage_device_admin); } @Override diff --git a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java index 67b78fcab1b..fdb93490a0c 100644 --- a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java +++ b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java @@ -67,7 +67,7 @@ public class ChangeScreenLockPreferenceController extends AbstractPreferenceCont @Override public boolean isAvailable() { - return true; + return mContext.getResources().getBoolean(R.bool.config_show_unlock_set_or_change); } @Override diff --git a/src/com/android/settings/security/ScreenPinningPreferenceController.java b/src/com/android/settings/security/ScreenPinningPreferenceController.java index 01ccbaac8b7..305d07699ba 100644 --- a/src/com/android/settings/security/ScreenPinningPreferenceController.java +++ b/src/com/android/settings/security/ScreenPinningPreferenceController.java @@ -33,7 +33,8 @@ public class ScreenPinningPreferenceController extends BasePreferenceController @Override public int getAvailabilityStatus() { - return AVAILABLE; + return mContext.getResources().getBoolean(R.bool.config_show_screen_pinning_settings) + ? AVAILABLE : DISABLED_UNSUPPORTED; } @Override diff --git a/src/com/android/settings/security/ShowPasswordPreferenceController.java b/src/com/android/settings/security/ShowPasswordPreferenceController.java index d0216e8e1b3..82f1935cee0 100644 --- a/src/com/android/settings/security/ShowPasswordPreferenceController.java +++ b/src/com/android/settings/security/ShowPasswordPreferenceController.java @@ -23,6 +23,7 @@ import android.provider.Settings; import com.android.internal.widget.LockPatternUtils; import com.android.settings.core.TogglePreferenceController; import com.android.settings.overlay.FeatureFactory; +import com.android.settings.R; public class ShowPasswordPreferenceController extends TogglePreferenceController { @@ -53,7 +54,9 @@ public class ShowPasswordPreferenceController extends TogglePreferenceController @Override public int getAvailabilityStatus() { - return AVAILABLE; + return mContext.getResources().getBoolean(R.bool.config_show_show_password) + ? AVAILABLE : DISABLED_UNSUPPORTED; } + } diff --git a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java index c615effe35d..5bb8f75e578 100644 --- a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java +++ b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java @@ -47,7 +47,8 @@ public class ManageTrustAgentsPreferenceController extends BasePreferenceControl @Override public int getAvailabilityStatus() { - return AVAILABLE; + return mContext.getResources().getBoolean(R.bool.config_show_manage_trust_agents) + ? AVAILABLE : DISABLED_UNSUPPORTED; } @Override diff --git a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java index 0fcee906bb4..f9e6a4c872b 100644 --- a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java +++ b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java @@ -79,7 +79,7 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro @Override public boolean isAvailable() { - return true; + return mContext.getResources().getBoolean(R.bool.config_show_trust_agent_click_intent); } @Override diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml index 639e1a2a329..a3205f33f29 100644 --- a/tests/robotests/res/values-mcc999/config.xml +++ b/tests/robotests/res/values-mcc999/config.xml @@ -36,6 +36,12 @@ false false false + false + false + false + false + false + false false false false diff --git a/tests/robotests/src/com/android/settings/enterprise/ManageDeviceAdminPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/ManageDeviceAdminPreferenceControllerTest.java index 5874984873e..d4494193809 100644 --- a/tests/robotests/src/com/android/settings/enterprise/ManageDeviceAdminPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/ManageDeviceAdminPreferenceControllerTest.java @@ -17,9 +17,12 @@ package com.android.settings.enterprise; 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.content.res.Resources; import android.support.v7.preference.Preference; import com.android.settings.R; @@ -33,6 +36,7 @@ import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; /** @@ -42,15 +46,17 @@ import org.robolectric.annotation.Config; @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public final class ManageDeviceAdminPreferenceControllerTest { - @Mock(answer = Answers.RETURNS_DEEP_STUBS) + @Mock + private Resources mResources; + private Context mContext; private FakeFeatureFactory mFeatureFactory; - private ManageDeviceAdminPreferenceController mController; @Before public void setUp() { MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); mFeatureFactory = FakeFeatureFactory.setupForTest(); mController = new ManageDeviceAdminPreferenceController(mContext); } @@ -61,24 +67,31 @@ public final class ManageDeviceAdminPreferenceControllerTest { when(mFeatureFactory.enterprisePrivacyFeatureProvider .getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile()).thenReturn(0); - when(mContext.getResources().getString(R.string.number_of_device_admins_none)) + when (mContext.getResources()).thenReturn(mResources); + when(mResources.getString(R.string.number_of_device_admins_none)) .thenReturn("no apps"); mController.updateState(preference); assertThat(preference.getSummary()).isEqualTo("no apps"); when(mFeatureFactory.enterprisePrivacyFeatureProvider .getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile()).thenReturn(5); - when(mContext.getResources().getQuantityString(R.plurals.number_of_device_admins, 5, 5)) + when(mResources.getQuantityString(R.plurals.number_of_device_admins, 5, 5)) .thenReturn("5 active apps"); mController.updateState(preference); assertThat(preference.getSummary()).isEqualTo("5 active apps"); } @Test - public void testIsAvailable() { + public void isAvailable_byDefault_isTrue() { assertThat(mController.isAvailable()).isTrue(); } + @Test + @Config(qualifiers = "mcc999") + public void isAvailable_whenNotVisible_isFalse() { + assertThat(mController.isAvailable()).isFalse(); + } + @Test public void testHandlePreferenceTreeClick() { assertThat(mController.handlePreferenceTreeClick(new Preference(mContext, null, 0, 0))) diff --git a/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java new file mode 100644 index 00000000000..4aaf5f499a7 --- /dev/null +++ b/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2018 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.security; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.os.UserManager; + +import com.android.internal.widget.LockPatternUtils; +import com.android.settings.TestConfig; +import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config( + manifest = TestConfig.MANIFEST_PATH, + sdk = TestConfig.SDK_VERSION, + shadows = { + ShadowUtils.class + }) +public class ChangeScreenLockPreferenceControllerTest { + + @Mock + private LockPatternUtils mLockPatternUtils; + @Mock + private UserManager mUserManager; + @Mock + private DevicePolicyManager mDevicePolicyManager; + + private Context mContext; + private FakeFeatureFactory mFeatureFactory; + private ChangeScreenLockPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application.getApplicationContext()); + mFeatureFactory = FakeFeatureFactory.setupForTest(); + when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(mContext)) + .thenReturn(mLockPatternUtils); + when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); + when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)) + .thenReturn(mDevicePolicyManager); + mController = new ChangeScreenLockPreferenceController(mContext, null /* Host */ ); + } + + @Test + public void testDeviceAdministrators_byDefault_shouldBeShown() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + @Config(qualifiers = "mcc999") + public void testDeviceAdministrators_ifDisabled_shouldNotBeShown() { + assertThat(mController.isAvailable()).isFalse(); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/security/ScreenPinningPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/ScreenPinningPreferenceControllerTest.java index 4ee9206dcfd..c5177acc109 100644 --- a/tests/robotests/src/com/android/settings/security/ScreenPinningPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/ScreenPinningPreferenceControllerTest.java @@ -59,8 +59,14 @@ public class ScreenPinningPreferenceControllerTest { } @Test - public void isAlwaysAvailable() { - assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + public void isAvailable_byDefault_isTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + @Config(qualifiers = "mcc999") + public void isAvailable_whenNotVisible_isFalse() { + assertThat(mController.isAvailable()).isFalse(); } @Test diff --git a/tests/robotests/src/com/android/settings/security/ShowPasswordPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/ShowPasswordPreferenceControllerTest.java index 63cf00b9d43..6bcb1d37410 100644 --- a/tests/robotests/src/com/android/settings/security/ShowPasswordPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/ShowPasswordPreferenceControllerTest.java @@ -70,8 +70,14 @@ public class ShowPasswordPreferenceControllerTest { } @Test - public void isAlwaysAvailable() { - assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + public void isAvailable_byDefault_isTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + @Config(qualifiers = "mcc999") + public void isAvailable_whenNotVisible_isFalse() { + assertThat(mController.isAvailable()).isFalse(); } @Test diff --git a/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java index 88186026b93..42d640a8a10 100644 --- a/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java @@ -75,8 +75,14 @@ public class ManageTrustAgentsPreferenceControllerTest { } @Test - public void isAlwaysAvailable() { - assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + public void isAvailable_byDefault_isTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + @Config(qualifiers = "mcc999") + public void isAvailable_whenNotVisible_isFalse() { + assertThat(mController.isAvailable()).isFalse(); } @Test diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java index 63348e62a35..11c3b3ffecf 100644 --- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java @@ -103,6 +103,12 @@ public class TrustAgentListPreferenceControllerTest { assertThat(mController).isInstanceOf(PreferenceControllerMixin.class); } + @Test + @Config(qualifiers = "mcc999") + public void isAvailable_whenNotVisible_isFalse() { + assertThat(mController.isAvailable()).isFalse(); + } + @Test public void onResume_shouldClearOldAgents() { final Preference oldAgent = new Preference(mActivity); From cf6d84109b73e8595ca43e41ac8a18d8317b4cdc Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Wed, 17 Jan 2018 11:40:15 -0800 Subject: [PATCH 10/30] Don't add any trust agents if the controller is not available. TrustAgentListPreferenceController gets a list of trust agents and add them to the security_category preference category at runtime. However, this update process is always ran - even if the controller is explicitly disabled/not available. This fixes this. Bug: None Test: Updated TrustAgentListPreferenceControllerTest. Change-Id: Ic95d219bc1d0c7cfa0c4eed0d3dd12dec0e14df6 --- .../TrustAgentListPreferenceController.java | 4 ++++ ...rustAgentListPreferenceControllerTest.java | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java index f9e6a4c872b..0c591ede39d 100644 --- a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java +++ b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java @@ -146,6 +146,10 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro mSecurityCategory.removePreference(oldAgent); } } + // If for some reason the preference is no longer available, don't proceed to add. + if (!isAvailable()) { + return; + } // Then add new ones. final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID); final List agents = diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java index 11c3b3ffecf..7dd04c641e9 100644 --- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java @@ -25,6 +25,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -141,4 +142,24 @@ public class TrustAgentListPreferenceControllerTest { verify(mCategory, atLeastOnce()).addPreference(any(Preference.class)); } + + @Test + @Config(qualifiers = "mcc999") + public void onResume_ifNotAvailable_shouldNotAddNewAgents() { + final List agents = new ArrayList<>(); + final TrustAgentManager.TrustAgentComponentInfo agent = mock( + TrustAgentManager.TrustAgentComponentInfo.class); + agent.title = "Test_title"; + agent.summary = "test summary"; + agent.componentName = new ComponentName("pkg", "agent"); + agent.admin = null; + agents.add(agent); + when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils)) + .thenReturn(agents); + + mController.displayPreference(mScreen); + mController.onResume(); + + verify(mCategory, never()).addPreference(any(Preference.class)); + } } From ab1f251defe8ee327917b1788f5702ae2c231a47 Mon Sep 17 00:00:00 2001 From: yuemingw Date: Wed, 10 Jan 2018 21:22:09 +0000 Subject: [PATCH 11/30] Change Settings to use URL_FILTERED and blocks menu options when DPC Apns are enforced. Change-Id: I64f55d9a625097baa17c0fa05250d944dea09896 Fix: 68208277 Test: manual --- src/com/android/settings/ApnPreference.java | 5 ++-- src/com/android/settings/ApnSettings.java | 29 ++++++++++++++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/com/android/settings/ApnPreference.java b/src/com/android/settings/ApnPreference.java index 0111b26194c..4e89efc781c 100755 --- a/src/com/android/settings/ApnPreference.java +++ b/src/com/android/settings/ApnPreference.java @@ -16,11 +16,12 @@ package com.android.settings; +import static android.provider.Telephony.Carriers.FILTERED_URI; + import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.provider.Telephony; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceViewHolder; import android.telephony.SubscriptionManager; @@ -118,7 +119,7 @@ public class ApnPreference extends Preference implements Context context = getContext(); if (context != null) { int pos = Integer.parseInt(getKey()); - Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos); + Uri url = ContentUris.withAppendedId(FILTERED_URI, pos); Intent editIntent = new Intent(Intent.ACTION_EDIT, url); editIntent.putExtra(ApnSettings.SUB_ID, mSubId); context.startActivity(editIntent); diff --git a/src/com/android/settings/ApnSettings.java b/src/com/android/settings/ApnSettings.java index d554301063c..3628121808e 100755 --- a/src/com/android/settings/ApnSettings.java +++ b/src/com/android/settings/ApnSettings.java @@ -16,6 +16,9 @@ package com.android.settings; +import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI; +import static android.provider.Telephony.Carriers.FILTERED_URI; + import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; @@ -39,7 +42,6 @@ import android.os.UserManager; import android.provider.Telephony; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceGroup; -import android.support.v7.preference.PreferenceScreen; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -50,7 +52,6 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; -import android.widget.TextView; import android.widget.Toast; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -246,6 +247,17 @@ public class ApnSettings extends RestrictedSettingsFragment implements return null; } + private boolean isDpcApnEnforced() { + try (Cursor enforceCursor = getContentResolver().query(ENFORCE_MANAGED_URI, + null, null, null, null)) { + if (enforceCursor == null || enforceCursor.getCount() != 1) { + return false; + } + enforceCursor.moveToFirst(); + return enforceCursor.getInt(0) > 0; + } + } + private void fillList() { final TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); final int subId = mSubscriptionInfo != null ? mSubscriptionInfo.getSubscriptionId() @@ -259,9 +271,9 @@ public class ApnSettings extends RestrictedSettingsFragment implements where.append(" AND NOT (type='ims')"); } - Cursor cursor = getContentResolver().query(Telephony.Carriers.CONTENT_URI, new String[] { - "_id", "name", "apn", "type", "mvno_type", "mvno_match_data"}, where.toString(), - null, Telephony.Carriers.DEFAULT_SORT_ORDER); + Cursor cursor = getContentResolver().query(FILTERED_URI, + new String[] {"_id", "name", "apn", "type", "mvno_type", "mvno_match_data"}, + where.toString(), null, Telephony.Carriers.DEFAULT_SORT_ORDER); if (cursor != null) { IccRecords r = null; @@ -343,15 +355,14 @@ public class ApnSettings extends RestrictedSettingsFragment implements @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - if (!mUnavailable) { + if (!mUnavailable && !isDpcApnEnforced()) { if (mAllowAddingApns) { menu.add(0, MENU_NEW, 0, getResources().getString(R.string.menu_new)) .setIcon(R.drawable.ic_menu_add_white) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); } - menu.add(0, MENU_RESTORE, 0, - getResources().getString(R.string.menu_restore)) + menu.add(0, MENU_RESTORE, 0, getResources().getString(R.string.menu_restore)) .setIcon(android.R.drawable.ic_menu_upload); } @@ -387,7 +398,7 @@ public class ApnSettings extends RestrictedSettingsFragment implements @Override public boolean onPreferenceTreeClick(Preference preference) { int pos = Integer.parseInt(preference.getKey()); - Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos); + Uri url = ContentUris.withAppendedId(FILTERED_URI, pos); startActivity(new Intent(Intent.ACTION_EDIT, url)); return true; } From 60b8bee9f7acf654216520bc5806557695c86cb3 Mon Sep 17 00:00:00 2001 From: Ningyuan Wang Date: Wed, 17 Jan 2018 14:23:42 -0800 Subject: [PATCH 12/30] Remove roam scan developer settings Bug: 72116071 Test: compile Test: m RunSettingsRoboTests -j40 Test: Manually check developer options, make sure roam scan is gone Change-Id: Ibe9fb31551962ecbb2979d0d2ec6885838b919b7 --- res/xml/development_settings.xml | 5 - .../DevelopmentSettingsDashboardFragment.java | 1 - .../WifiRoamScansPreferenceController.java | 85 -------------- ...WifiRoamScansPreferenceControllerTest.java | 110 ------------------ 4 files changed, 201 deletions(-) delete mode 100644 src/com/android/settings/development/WifiRoamScansPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/development/WifiRoamScansPreferenceControllerTest.java diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 1daeb49b6c5..9d85ec9c9a1 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -202,11 +202,6 @@ android:title="@string/wifi_verbose_logging" android:summary="@string/wifi_verbose_logging_summary"/> - - 0; - mPreference.setChecked(enabled); - } - - @Override - protected void onDeveloperOptionsSwitchEnabled() { - mPreference.setEnabled(true); - } - - @Override - protected void onDeveloperOptionsSwitchDisabled() { - mWifiManager.setAllowScansWithTraffic(SETTING_VALUE_OFF); - mPreference.setEnabled(false); - mPreference.setChecked(false); - } -} diff --git a/tests/robotests/src/com/android/settings/development/WifiRoamScansPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/WifiRoamScansPreferenceControllerTest.java deleted file mode 100644 index 60e5e4931d0..00000000000 --- a/tests/robotests/src/com/android/settings/development/WifiRoamScansPreferenceControllerTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2017 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.development; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.wifi.WifiManager; -import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.PreferenceScreen; - -import com.android.settings.TestConfig; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class WifiRoamScansPreferenceControllerTest { - - @Mock - private Context mContext; - @Mock - private WifiManager mWifiManager; - @Mock - private SwitchPreference mPreference; - @Mock - private PreferenceScreen mPreferenceScreen; - - private WifiRoamScansPreferenceController mController; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager); - mController = new WifiRoamScansPreferenceController(mContext); - when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn( - mPreference); - mController.displayPreference(mPreferenceScreen); - } - - @Test - public void onPreferenceChange_shouldEnableRoamScanning() { - mController.onPreferenceChange(mPreference, true /* new value */); - - verify(mWifiManager).setAllowScansWithTraffic( - WifiRoamScansPreferenceController.SETTING_VALUE_ON); - } - - @Test - public void onPreferenceChange_shouldDisableRoamScanning() { - mController.onPreferenceChange(mPreference, false /* new value */); - - verify(mWifiManager).setAllowScansWithTraffic( - WifiRoamScansPreferenceController.SETTING_VALUE_OFF); - } - - @Test - public void updateState_shouldEnablePreference() { - when(mWifiManager.getAllowScansWithTraffic()).thenReturn(1); - mController.updateState(mPreference); - - verify(mPreference).setChecked(true); - } - - @Test - public void updateState_shouldDisablePreference() { - when(mWifiManager.getAllowScansWithTraffic()).thenReturn(0); - mController.updateState(mPreference); - - verify(mPreference).setChecked(false); - } - - @Test - public void onDeveloperOptionsSwitchEnabled_shouldEnablePreference() { - mController.onDeveloperOptionsSwitchEnabled(); - - verify(mPreference).setEnabled(true); - } - - @Test - public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() { - mController.onDeveloperOptionsSwitchDisabled(); - - verify(mWifiManager).setAllowScansWithTraffic( - WifiRoamScansPreferenceController.SETTING_VALUE_OFF); - verify(mPreference).setEnabled(false); - verify(mPreference).setChecked(false); - } -} From e1bb0c2f4c2599378a297df5570d8ca91ced7023 Mon Sep 17 00:00:00 2001 From: Michael Rosenfeld Date: Thu, 18 Jan 2018 11:11:39 -0800 Subject: [PATCH 13/30] Fix build breakage dependency. Test: manual, builds Change-Id: I43bd8dedc48a268bdf6cfaaf1f4c524ef6d3b646 --- tests/uitests/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/uitests/Android.mk b/tests/uitests/Android.mk index 23357e8c4c6..870f59c17bd 100644 --- a/tests/uitests/Android.mk +++ b/tests/uitests/Android.mk @@ -21,7 +21,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_MODULE_TAGS := tests LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base LOCAL_STATIC_JAVA_LIBRARIES := \ - app-helpers-base \ + app-helpers-core \ launcher-helper-lib \ settings-helper \ timeresult-helper-lib \ From 1546cca529bf56430332e15b05ceb6efb37e57bf Mon Sep 17 00:00:00 2001 From: Leif Hendrik Wilden Date: Thu, 11 Jan 2018 10:15:36 -0800 Subject: [PATCH 14/30] Migrate to use instrumentation classes from settingslib. Test: Compiles. Manually tested. Change-Id: Ie5515bb0fe3e621fc7723a9b04ba23e4bfa9c401 --- .../android/settings/AirplaneModeEnabler.java | 2 +- .../android/settings/DeviceAdminSettings.java | 16 +- .../android/settings/SettingsActivity.java | 12 +- .../settings/SettingsPreferenceFragment.java | 2 +- src/com/android/settings/Utils.java | 3 +- .../accounts/AccountPreferenceController.java | 2 +- .../applications/UsageAccessDetails.java | 2 +- .../bluetooth/BluetoothDevicePreference.java | 2 +- ...toothDeviceRenamePreferenceController.java | 2 +- .../settings/bluetooth/BluetoothEnabler.java | 2 +- .../BluetoothFilesPreferenceController.java | 2 +- .../settings/core/InstrumentedActivity.java | 8 +- .../settings/core/InstrumentedFragment.java | 22 +- .../core/InstrumentedPreferenceFragment.java | 22 +- .../core/instrumentation/EventLogWriter.java | 110 -------- .../core/instrumentation/Instrumentable.java | 28 -- .../InstrumentedDialogFragment.java | 11 +- .../core/instrumentation/LogWriter.java | 84 ------ .../MetricsFeatureProvider.java | 159 ----------- .../SharedPreferencesLogger.java | 259 ------------------ .../VisibilityLoggerMixin.java | 100 ------- .../settings/dashboard/DashboardAdapter.java | 2 +- .../dashboard/DashboardAdapterV2.java | 2 +- .../DashboardFeatureProviderImpl.java | 8 +- .../dashboard/conditional/Condition.java | 2 +- .../conditional/ConditionAdapter.java | 2 +- .../conditional/ConditionAdapterV2.java | 2 +- .../suggestions/SuggestionAdapter.java | 2 +- .../suggestions/SuggestionAdapterV2.java | 2 +- .../SuggestionFeatureProviderImpl.java | 2 +- .../settings/datausage/DataSaverBackend.java | 2 +- .../android/settings/datetime/ZonePicker.java | 21 +- ...aticStorageManagerSwitchBarController.java | 6 +- .../BuildNumberPreferenceController.java | 2 +- ...eManagementSwitchPreferenceController.java | 2 +- .../StorageItemPreferenceController.java | 2 +- ...playNotificationsPreferenceController.java | 2 +- .../display/AmbientDisplaySettings.java | 2 +- .../AutoRotatePreferenceController.java | 2 +- .../display/ThemePreferenceController.java | 2 +- .../AppButtonsPreferenceController.java | 2 +- .../BatteryAppListPreferenceController.java | 2 +- .../settings/fuelgauge/PowerUsageSummary.java | 2 +- .../fuelgauge/PowerUsageSummaryLegacy.java | 2 +- .../fuelgauge/anomaly/AnomalyUtils.java | 2 +- .../anomaly/action/AnomalyAction.java | 2 +- .../batterytip/actions/BatteryTipAction.java | 2 +- .../actions/SmartBatteryAction.java | 2 +- .../inputmethod/UserDictionarySettings.java | 17 +- .../AirplaneModePreferenceController.java | 2 +- .../network/NetworkDashboardFragment.java | 2 +- .../AbstractZenModePreferenceController.java | 2 +- .../notification/ZenRulePreference.java | 4 +- .../settings/overlay/FeatureFactory.java | 2 +- .../settings/overlay/FeatureFactoryImpl.java | 2 +- .../android/settings/widget/SwitchBar.java | 2 +- .../android/settings/wifi/WifiEnabler.java | 2 +- .../WifiMasterSwitchPreferenceController.java | 2 +- .../WifiDetailPreferenceController.java | 2 +- .../settings/SettingsDialogFragmentTest.java | 7 +- .../InstantAppButtonsControllerTest.java | 2 +- .../BluetoothDevicePreferenceTest.java | 2 +- .../bluetooth/BluetoothEnablerTest.java | 2 +- .../android/settings/bluetooth/UtilsTest.java | 2 +- .../InstrumentableFragmentCodeInspector.java | 1 + .../InstrumentedDialogFragmentTest.java | 1 + .../MetricsFeatureProviderTest.java | 66 +---- .../SharedPreferenceLoggerTest.java | 185 ------------- .../VisibilityLoggerMixinTest.java | 123 --------- .../DashboardFeatureProviderImplTest.java | 3 +- .../dashboard/DashboardFragmentTest.java | 2 +- .../dashboard/conditional/ConditionTest.java | 2 +- .../settings/datausage/DataUsageListTest.java | 1 + .../settings/datetime/ZonePickerTest.java | 2 +- ...StorageManagerSwitchBarControllerTest.java | 2 +- ...agementSwitchPreferenceControllerTest.java | 2 +- .../StorageItemPreferenceControllerTest.java | 2 +- ...eSummaryDonutPreferenceControllerTest.java | 2 +- ...NotificationsPreferenceControllerTest.java | 2 +- .../FingerprintEnrollEnrollingTest.java | 4 + .../FingerprintEnrollFindSensorTest.java | 4 + .../FingerprintSuggestionActivityTest.java | 4 + .../SetupFingerprintEnrollFindSensorTest.java | 4 + ...etupFingerprintEnrollIntroductionTest.java | 4 + .../fuelgauge/anomaly/AnomalyUtilsTest.java | 2 +- .../localepicker/LocaleListEditorTest.java | 10 + .../testutils/FakeFeatureFactory.java | 2 +- .../shadow/ShadowEventLogWriter.java | 2 +- .../webview/WebViewAppPickerTest.java | 2 +- .../settings/wifi/WifiEnablerTest.java | 2 +- ...iMasterSwitchPreferenceControllerTest.java | 2 +- .../WifiDetailPreferenceControllerTest.java | 2 +- 92 files changed, 177 insertions(+), 1250 deletions(-) delete mode 100644 src/com/android/settings/core/instrumentation/EventLogWriter.java delete mode 100644 src/com/android/settings/core/instrumentation/Instrumentable.java delete mode 100644 src/com/android/settings/core/instrumentation/LogWriter.java delete mode 100644 src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java delete mode 100644 src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java delete mode 100644 src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java delete mode 100644 tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java delete mode 100644 tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java index 4fc205d263d..5f93589c92d 100644 --- a/src/com/android/settings/AirplaneModeEnabler.java +++ b/src/com/android/settings/AirplaneModeEnabler.java @@ -30,8 +30,8 @@ import android.support.v7.preference.Preference; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.PhoneStateIntentReceiver; import com.android.internal.telephony.TelephonyProperties; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.WirelessUtils; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListener { diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/DeviceAdminSettings.java index 9391439267d..bb53018dfd6 100644 --- a/src/com/android/settings/DeviceAdminSettings.java +++ b/src/com/android/settings/DeviceAdminSettings.java @@ -49,8 +49,9 @@ import android.widget.Switch; import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto; -import com.android.settings.core.instrumentation.Instrumentable; -import com.android.settings.core.instrumentation.VisibilityLoggerMixin; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.Instrumentable; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import org.xmlpull.v1.XmlPullParserException; @@ -63,8 +64,7 @@ import java.util.List; public class DeviceAdminSettings extends ListFragment implements Instrumentable { static final String TAG = "DeviceAdminSettings"; - private final VisibilityLoggerMixin mVisibilityLoggerMixin = - new VisibilityLoggerMixin(getMetricsCategory()); + private VisibilityLoggerMixin mVisibilityLoggerMixin; private DevicePolicyManager mDPM; private UserManager mUm; @@ -85,12 +85,6 @@ public class DeviceAdminSettings extends ListFragment implements Instrumentable } } - @Override - public void onAttach(Context context) { - super.onAttach(context); - mVisibilityLoggerMixin.onAttach(context); - } - /** * Internal collection of device admin info objects for all profiles associated with the current * user. @@ -121,6 +115,8 @@ public class DeviceAdminSettings extends ListFragment implements Instrumentable @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); + mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(), + FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()); } @Override diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index d3580d18b86..5cb7c06c21a 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -56,13 +56,13 @@ import com.android.settings.Settings.WifiSettingsActivity; import com.android.settings.applications.manageapplications.ManageApplications; import com.android.settings.backup.BackupSettingsActivity; import com.android.settings.core.gateway.SettingsGateway; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; -import com.android.settings.core.instrumentation.SharedPreferencesLogger; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.DashboardSummary; import com.android.settings.overlay.FeatureFactory; import com.android.settings.wfd.WifiDisplaySettings; import com.android.settings.widget.SwitchBar; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.core.instrumentation.SharedPreferencesLogger; import com.android.settingslib.development.DevelopmentSettingsEnabler; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.SettingsDrawerActivity; @@ -92,11 +92,6 @@ public class SettingsActivity extends SettingsDrawerActivity */ public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment"; - /** - * The metrics category constant for logging source when a setting fragment is opened. - */ - public static final String EXTRA_SOURCE_METRICS_CATEGORY = ":settings:source_metrics"; - /** * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT}, * this extra can also be specified to supply a Bundle of arguments to pass @@ -220,7 +215,8 @@ public class SettingsActivity extends SettingsDrawerActivity @Override public SharedPreferences getSharedPreferences(String name, int mode) { if (name.equals(getPackageName() + "_preferences")) { - return new SharedPreferencesLogger(this, getMetricsTag()); + return new SharedPreferencesLogger(this, getMetricsTag(), + FeatureFactory.getFactory(this).getMetricsFeatureProvider()); } return super.getSharedPreferences(name, mode); } diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index d9e264bf33d..c5d477aad0b 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -45,7 +45,6 @@ import android.widget.Button; import com.android.settings.applications.LayoutPreference; import com.android.settings.core.InstrumentedPreferenceFragment; -import com.android.settings.core.instrumentation.Instrumentable; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.search.actionbar.SearchMenuController; import com.android.settings.support.actionbar.HelpMenuController; @@ -53,6 +52,7 @@ import com.android.settings.support.actionbar.HelpResourceProvider; import com.android.settings.widget.LoadingViewController; import com.android.settingslib.CustomDialogPreference; import com.android.settingslib.CustomEditTextPreference; +import com.android.settingslib.core.instrumentation.Instrumentable; import com.android.settingslib.widget.FooterPreferenceMixin; import java.util.UUID; diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index ad951216781..1c674b68f15 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -110,6 +110,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settings.wrapper.FingerprintManagerWrapper; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import java.net.InetAddress; import java.util.ArrayList; @@ -576,7 +577,7 @@ public final class Utils extends com.android.settingslib.Utils { intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, titleResId); intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE, title); intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, isShortcut); - intent.putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, sourceMetricsCategory); + intent.putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY, sourceMetricsCategory); return intent; } diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java index c0bf7d21ef9..6127ab9bccc 100644 --- a/src/com/android/settings/accounts/AccountPreferenceController.java +++ b/src/com/android/settings/accounts/AccountPreferenceController.java @@ -51,12 +51,12 @@ import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.SearchIndexableRaw; import com.android.settingslib.RestrictedPreference; import com.android.settingslib.accounts.AuthenticatorHelper; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; diff --git a/src/com/android/settings/applications/UsageAccessDetails.java b/src/com/android/settings/applications/UsageAccessDetails.java index c10fb55c9ec..c172137664b 100644 --- a/src/com/android/settings/applications/UsageAccessDetails.java +++ b/src/com/android/settings/applications/UsageAccessDetails.java @@ -37,8 +37,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.applications.AppStateUsageBridge.UsageState; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; public class UsageAccessDetails extends AppInfoWithHeader implements OnPreferenceChangeListener, OnPreferenceClickListener { diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index a0ce73386a5..3fd7ced3e03 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -33,10 +33,10 @@ import android.widget.ImageView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.GearPreference; import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH; diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java index a12d1a8ecb2..cea0147cecf 100644 --- a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java +++ b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java @@ -23,9 +23,9 @@ import android.support.v7.preference.Preference; import android.text.TextUtils; import com.android.internal.logging.nano.MetricsProto; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.bluetooth.LocalBluetoothAdapter; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; public class BluetoothDeviceRenamePreferenceController extends diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java index 87fa43d2db2..0f294bd5748 100644 --- a/src/com/android/settings/bluetooth/BluetoothEnabler.java +++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java @@ -27,12 +27,12 @@ import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.widget.SwitchWidgetController; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.WirelessUtils; import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; /** * BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox diff --git a/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java index 450c7b2320a..1ecfed42515 100644 --- a/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java +++ b/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java @@ -23,9 +23,9 @@ import android.support.v7.preference.Preference; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; /** * Controller that shows received files diff --git a/src/com/android/settings/core/InstrumentedActivity.java b/src/com/android/settings/core/InstrumentedActivity.java index 9b24756b19e..294de2cb957 100644 --- a/src/com/android/settings/core/InstrumentedActivity.java +++ b/src/com/android/settings/core/InstrumentedActivity.java @@ -16,8 +16,9 @@ package com.android.settings.core; -import com.android.settings.core.instrumentation.Instrumentable; -import com.android.settings.core.instrumentation.VisibilityLoggerMixin; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.Instrumentable; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.core.lifecycle.ObservableActivity; /** @@ -27,7 +28,8 @@ public abstract class InstrumentedActivity extends ObservableActivity implements public InstrumentedActivity() { // Mixin that logs visibility change for activity. - getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory())); + getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory(), + FeatureFactory.getFactory(this).getMetricsFeatureProvider())); } } diff --git a/src/com/android/settings/core/InstrumentedFragment.java b/src/com/android/settings/core/InstrumentedFragment.java index 45db836efcc..b1215b9ac4a 100644 --- a/src/com/android/settings/core/InstrumentedFragment.java +++ b/src/com/android/settings/core/InstrumentedFragment.java @@ -18,30 +18,28 @@ package com.android.settings.core; import android.content.Context; -import com.android.settings.core.instrumentation.Instrumentable; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; -import com.android.settings.core.instrumentation.VisibilityLoggerMixin; import com.android.settings.overlay.FeatureFactory; import com.android.settings.survey.SurveyMixin; +import com.android.settingslib.core.instrumentation.Instrumentable; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.core.lifecycle.ObservableFragment; public abstract class InstrumentedFragment extends ObservableFragment implements Instrumentable { protected MetricsFeatureProvider mMetricsFeatureProvider; - private final VisibilityLoggerMixin mVisibilityLoggerMixin; - - public InstrumentedFragment() { - // Mixin that logs visibility change for activity. - mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory()); - getLifecycle().addObserver(mVisibilityLoggerMixin); - getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName())); - } + private VisibilityLoggerMixin mVisibilityLoggerMixin; @Override public void onAttach(Context context) { - super.onAttach(context); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); + mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(), + mMetricsFeatureProvider); + // Mixin that logs visibility change for activity. + getLifecycle().addObserver(mVisibilityLoggerMixin); + getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName())); + super.onAttach(context); } @Override diff --git a/src/com/android/settings/core/InstrumentedPreferenceFragment.java b/src/com/android/settings/core/InstrumentedPreferenceFragment.java index 7e37115bab0..278676c52ea 100644 --- a/src/com/android/settings/core/InstrumentedPreferenceFragment.java +++ b/src/com/android/settings/core/InstrumentedPreferenceFragment.java @@ -23,11 +23,11 @@ import android.support.v7.preference.PreferenceScreen; import android.text.TextUtils; import android.util.Log; -import com.android.settings.core.instrumentation.Instrumentable; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; -import com.android.settings.core.instrumentation.VisibilityLoggerMixin; import com.android.settings.overlay.FeatureFactory; import com.android.settings.survey.SurveyMixin; +import com.android.settingslib.core.instrumentation.Instrumentable; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment; /** @@ -44,19 +44,17 @@ public abstract class InstrumentedPreferenceFragment extends ObservablePreferenc // metrics placeholder value. Only use this for development. protected final int PLACEHOLDER_METRIC = 10000; - private final VisibilityLoggerMixin mVisibilityLoggerMixin; - - public InstrumentedPreferenceFragment() { - // Mixin that logs visibility change for activity. - mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory()); - getLifecycle().addObserver(mVisibilityLoggerMixin); - getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName())); - } + private VisibilityLoggerMixin mVisibilityLoggerMixin; @Override public void onAttach(Context context) { - super.onAttach(context); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); + // Mixin that logs visibility change for activity. + mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(), + mMetricsFeatureProvider); + getLifecycle().addObserver(mVisibilityLoggerMixin); + getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName())); + super.onAttach(context); } @Override diff --git a/src/com/android/settings/core/instrumentation/EventLogWriter.java b/src/com/android/settings/core/instrumentation/EventLogWriter.java deleted file mode 100644 index 3196f76b323..00000000000 --- a/src/com/android/settings/core/instrumentation/EventLogWriter.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.core.instrumentation; - -import android.content.Context; -import android.metrics.LogMaker; -import android.util.Log; -import android.util.Pair; - -import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto; - -/** - * {@link LogWriter} that writes data to eventlog. - */ -public class EventLogWriter implements LogWriter { - - private final MetricsLogger mMetricsLogger = new MetricsLogger(); - - public void visible(Context context, int source, int category) { - final LogMaker logMaker = new LogMaker(category) - .setType(MetricsProto.MetricsEvent.TYPE_OPEN) - .addTaggedData(MetricsProto.MetricsEvent.FIELD_CONTEXT, source); - MetricsLogger.action(logMaker); - } - - public void hidden(Context context, int category) { - MetricsLogger.hidden(context, category); - } - - public void action(int category, int value, Pair... taggedData) { - if (taggedData == null || taggedData.length == 0) { - mMetricsLogger.action(category, value); - } else { - final LogMaker logMaker = new LogMaker(category) - .setType(MetricsProto.MetricsEvent.TYPE_ACTION) - .setSubtype(value); - for (Pair pair : taggedData) { - logMaker.addTaggedData(pair.first, pair.second); - } - mMetricsLogger.write(logMaker); - } - } - - public void action(int category, boolean value, Pair... taggedData) { - action(category, value ? 1 : 0, taggedData); - } - - public void action(Context context, int category, Pair... taggedData) { - action(context, category, "", taggedData); - } - - public void actionWithSource(Context context, int source, int category) { - final LogMaker logMaker = new LogMaker(category) - .setType(MetricsProto.MetricsEvent.TYPE_ACTION); - if (source != MetricsProto.MetricsEvent.VIEW_UNKNOWN) { - logMaker.addTaggedData(MetricsProto.MetricsEvent.FIELD_CONTEXT, source); - } - MetricsLogger.action(logMaker); - } - - /** @deprecated use {@link #action(int, int, Pair[])} */ - @Deprecated - public void action(Context context, int category, int value) { - MetricsLogger.action(context, category, value); - } - - /** @deprecated use {@link #action(int, boolean, Pair[])} */ - @Deprecated - public void action(Context context, int category, boolean value) { - MetricsLogger.action(context, category, value); - } - - public void action(Context context, int category, String pkg, - Pair... taggedData) { - if (taggedData == null || taggedData.length == 0) { - MetricsLogger.action(context, category, pkg); - } else { - final LogMaker logMaker = new LogMaker(category) - .setType(MetricsProto.MetricsEvent.TYPE_ACTION) - .setPackageName(pkg); - for (Pair pair : taggedData) { - logMaker.addTaggedData(pair.first, pair.second); - } - MetricsLogger.action(logMaker); - } - } - - public void count(Context context, String name, int value) { - MetricsLogger.count(context, name, value); - } - - public void histogram(Context context, String name, int bucket) { - MetricsLogger.histogram(context, name, bucket); - } -} diff --git a/src/com/android/settings/core/instrumentation/Instrumentable.java b/src/com/android/settings/core/instrumentation/Instrumentable.java deleted file mode 100644 index f58e140b62a..00000000000 --- a/src/com/android/settings/core/instrumentation/Instrumentable.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.core.instrumentation; - -public interface Instrumentable { - - int METRICS_CATEGORY_UNKNOWN = 0; - - /** - * Instrumented name for a view as defined in - * {@link com.android.internal.logging.nano.MetricsProto.MetricsEvent}. - */ - int getMetricsCategory(); -} diff --git a/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java b/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java index 5a9ab56ea99..0a214f17315 100644 --- a/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java +++ b/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java @@ -19,6 +19,9 @@ import android.content.Context; import com.android.settings.DialogCreatable; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.Instrumentable; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.core.lifecycle.ObservableDialogFragment; public abstract class InstrumentedDialogFragment extends ObservableDialogFragment @@ -38,13 +41,15 @@ public abstract class InstrumentedDialogFragment extends ObservableDialogFragmen public InstrumentedDialogFragment(DialogCreatable dialogCreatable, int dialogId) { mDialogCreatable = dialogCreatable; mDialogId = dialogId; - mLifecycle.addObserver(new VisibilityLoggerMixin(getMetricsCategory())); } - @Override public void onAttach(Context context) { super.onAttach(context); - mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); + mMetricsFeatureProvider = FeatureFactory.getFactory(context) + .getMetricsFeatureProvider(); + mLifecycle.addObserver(new VisibilityLoggerMixin(getMetricsCategory(), + mMetricsFeatureProvider)); + mLifecycle.onAttach(context); } } diff --git a/src/com/android/settings/core/instrumentation/LogWriter.java b/src/com/android/settings/core/instrumentation/LogWriter.java deleted file mode 100644 index 062d46f759f..00000000000 --- a/src/com/android/settings/core/instrumentation/LogWriter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.settings.core.instrumentation; - -import android.content.Context; -import android.util.Pair; - -/** - * Generic log writer interface. - */ -public interface LogWriter { - - /** - * Logs a visibility event when view becomes visible. - */ - void visible(Context context, int source, int category); - - /** - * Logs a visibility event when view becomes hidden. - */ - void hidden(Context context, int category); - - /** - * Logs a user action. - */ - void action(int category, int value, Pair... taggedData); - - /** - * Logs a user action. - */ - void action(int category, boolean value, Pair... taggedData); - - /** - * Logs an user action. - */ - void action(Context context, int category, Pair... taggedData); - - /** - * Logs an user action. - */ - void actionWithSource(Context context, int source, int category); - - /** - * Logs an user action. - * @deprecated use {@link #action(int, int, Pair[])} - */ - @Deprecated - void action(Context context, int category, int value); - - /** - * Logs an user action. - * @deprecated use {@link #action(int, boolean, Pair[])} - */ - @Deprecated - void action(Context context, int category, boolean value); - - /** - * Logs an user action. - */ - void action(Context context, int category, String pkg, Pair... taggedData); - - /** - * Logs a count. - */ - void count(Context context, String name, int value); - - /** - * Logs a histogram event. - */ - void histogram(Context context, String name, int bucket); -} diff --git a/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java b/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java deleted file mode 100644 index 166cbb84471..00000000000 --- a/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.settings.core.instrumentation; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.text.TextUtils; -import android.util.Pair; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; - -import java.util.ArrayList; -import java.util.List; - -/** - * FeatureProvider for metrics. - */ -public class MetricsFeatureProvider { - private List mLoggerWriters; - - public MetricsFeatureProvider() { - mLoggerWriters = new ArrayList<>(); - installLogWriters(); - } - - protected void installLogWriters() { - mLoggerWriters.add(new EventLogWriter()); - } - - public void visible(Context context, int source, int category) { - for (LogWriter writer : mLoggerWriters) { - writer.visible(context, source, category); - } - } - - public void hidden(Context context, int category) { - for (LogWriter writer : mLoggerWriters) { - writer.hidden(context, category); - } - } - - public void actionWithSource(Context context, int source, int category) { - for (LogWriter writer : mLoggerWriters) { - writer.actionWithSource(context, source, category); - } - } - - /** - * Logs a user action. Includes the elapsed time since the containing - * fragment has been visible. - */ - public void action(VisibilityLoggerMixin visibilityLogger, int category, int value) { - for (LogWriter writer : mLoggerWriters) { - writer.action(category, value, - sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible())); - } - } - - /** - * Logs a user action. Includes the elapsed time since the containing - * fragment has been visible. - */ - public void action(VisibilityLoggerMixin visibilityLogger, int category, boolean value) { - for (LogWriter writer : mLoggerWriters) { - writer.action(category, value, - sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible())); - } - } - - public void action(Context context, int category, Pair... taggedData) { - for (LogWriter writer : mLoggerWriters) { - writer.action(context, category, taggedData); - } - } - - /** @deprecated use {@link #action(VisibilityLoggerMixin, int, int)} */ - @Deprecated - public void action(Context context, int category, int value) { - for (LogWriter writer : mLoggerWriters) { - writer.action(context, category, value); - } - } - - /** @deprecated use {@link #action(VisibilityLoggerMixin, int, boolean)} */ - @Deprecated - public void action(Context context, int category, boolean value) { - for (LogWriter writer : mLoggerWriters) { - writer.action(context, category, value); - } - } - - public void action(Context context, int category, String pkg, - Pair... taggedData) { - for (LogWriter writer : mLoggerWriters) { - writer.action(context, category, pkg, taggedData); - } - } - - public void count(Context context, String name, int value) { - for (LogWriter writer : mLoggerWriters) { - writer.count(context, name, value); - } - } - - public void histogram(Context context, String name, int bucket) { - for (LogWriter writer : mLoggerWriters) { - writer.histogram(context, name, bucket); - } - } - - public int getMetricsCategory(Object object) { - if (object == null || !(object instanceof Instrumentable)) { - return MetricsEvent.VIEW_UNKNOWN; - } - return ((Instrumentable) object).getMetricsCategory(); - } - - public void logDashboardStartIntent(Context context, Intent intent, - int sourceMetricsCategory) { - if (intent == null) { - return; - } - final ComponentName cn = intent.getComponent(); - if (cn == null) { - final String action = intent.getAction(); - if (TextUtils.isEmpty(action)) { - // Not loggable - return; - } - action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, action, - Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory)); - return; - } else if (TextUtils.equals(cn.getPackageName(), context.getPackageName())) { - // Going to a Setting internal page, skip click logging in favor of page's own - // visibility logging. - return; - } - action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, cn.flattenToString(), - Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory)); - } - - private Pair sinceVisibleTaggedData(long timestamp) { - return Pair.create(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS, timestamp); - } -} diff --git a/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java b/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java deleted file mode 100644 index dee40c043ce..00000000000 --- a/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.android.settings.core.instrumentation; - -import android.annotation.Nullable; -import android.content.ComponentName; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.os.AsyncTask; -import android.support.annotation.VisibleForTesting; -import android.text.TextUtils; -import android.util.Log; -import android.util.Pair; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.overlay.FeatureFactory; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentSkipListSet; - -public class SharedPreferencesLogger implements SharedPreferences { - - private static final String LOG_TAG = "SharedPreferencesLogger"; - - private final String mTag; - private final Context mContext; - private final MetricsFeatureProvider mMetricsFeature; - private final Set mPreferenceKeySet; - - public SharedPreferencesLogger(Context context, String tag) { - mContext = context; - mTag = tag; - mMetricsFeature = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); - mPreferenceKeySet = new ConcurrentSkipListSet<>(); - } - - @Override - public Map getAll() { - return null; - } - - @Override - public String getString(String key, @Nullable String defValue) { - return defValue; - } - - @Override - public Set getStringSet(String key, @Nullable Set defValues) { - return defValues; - } - - @Override - public int getInt(String key, int defValue) { - return defValue; - } - - @Override - public long getLong(String key, long defValue) { - return defValue; - } - - @Override - public float getFloat(String key, float defValue) { - return defValue; - } - - @Override - public boolean getBoolean(String key, boolean defValue) { - return defValue; - } - - @Override - public boolean contains(String key) { - return false; - } - - @Override - public Editor edit() { - return new EditorLogger(); - } - - @Override - public void registerOnSharedPreferenceChangeListener( - OnSharedPreferenceChangeListener listener) { - } - - @Override - public void unregisterOnSharedPreferenceChangeListener( - OnSharedPreferenceChangeListener listener) { - } - - private void logValue(String key, Object value) { - logValue(key, value, false /* forceLog */); - } - - private void logValue(String key, Object value, boolean forceLog) { - final String prefKey = buildPrefKey(mTag, key); - if (!forceLog && !mPreferenceKeySet.contains(prefKey)) { - // Pref key doesn't exist in set, this is initial display so we skip metrics but - // keeps track of this key. - mPreferenceKeySet.add(prefKey); - return; - } - // TODO: Remove count logging to save some resource. - mMetricsFeature.count(mContext, buildCountName(prefKey, value), 1); - - final Pair valueData; - if (value instanceof Long) { - final Long longVal = (Long) value; - final int intVal; - if (longVal > Integer.MAX_VALUE) { - intVal = Integer.MAX_VALUE; - } else if (longVal < Integer.MIN_VALUE) { - intVal = Integer.MIN_VALUE; - } else { - intVal = longVal.intValue(); - } - valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, - intVal); - } else if (value instanceof Integer) { - valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, - value); - } else if (value instanceof Boolean) { - valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, - (Boolean) value ? 1 : 0); - } else if (value instanceof Float) { - valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE, - value); - } else if (value instanceof String) { - Log.d(LOG_TAG, "Tried to log string preference " + prefKey + " = " + value); - valueData = null; - } else { - Log.w(LOG_TAG, "Tried to log unloggable object" + value); - valueData = null; - } - if (valueData != null) { - // Pref key exists in set, log it's change in metrics. - mMetricsFeature.action(mContext, MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE, - Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, prefKey), - valueData); - } - } - - @VisibleForTesting - void logPackageName(String key, String value) { - final String prefKey = mTag + "/" + key; - mMetricsFeature.action(mContext, MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE, value, - Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, prefKey)); - } - - private void safeLogValue(String key, String value) { - new AsyncPackageCheck().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, key, value); - } - - public static String buildCountName(String prefKey, Object value) { - return prefKey + "|" + value; - } - - public static String buildPrefKey(String tag, String key) { - return tag + "/" + key; - } - - private class AsyncPackageCheck extends AsyncTask { - @Override - protected Void doInBackground(String... params) { - String key = params[0]; - String value = params[1]; - PackageManager pm = mContext.getPackageManager(); - try { - // Check if this might be a component. - ComponentName name = ComponentName.unflattenFromString(value); - if (value != null) { - value = name.getPackageName(); - } - } catch (Exception e) { - } - try { - pm.getPackageInfo(value, PackageManager.MATCH_ANY_USER); - logPackageName(key, value); - } catch (PackageManager.NameNotFoundException e) { - // Clearly not a package, and it's unlikely this preference is in prefSet, so - // lets force log it. - logValue(key, value, true /* forceLog */); - } - return null; - } - } - - public class EditorLogger implements Editor { - @Override - public Editor putString(String key, @Nullable String value) { - safeLogValue(key, value); - return this; - } - - @Override - public Editor putStringSet(String key, @Nullable Set values) { - safeLogValue(key, TextUtils.join(",", values)); - return this; - } - - @Override - public Editor putInt(String key, int value) { - logValue(key, value); - return this; - } - - @Override - public Editor putLong(String key, long value) { - logValue(key, value); - return this; - } - - @Override - public Editor putFloat(String key, float value) { - logValue(key, value); - return this; - } - - @Override - public Editor putBoolean(String key, boolean value) { - logValue(key, value); - return this; - } - - @Override - public Editor remove(String key) { - return this; - } - - @Override - public Editor clear() { - return this; - } - - @Override - public boolean commit() { - return true; - } - - @Override - public void apply() { - } - } -} diff --git a/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java b/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java deleted file mode 100644 index 2fe2a3beb1d..00000000000 --- a/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.core.instrumentation; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; - -import android.os.SystemClock; -import com.android.internal.logging.nano.MetricsProto; -import com.android.settings.SettingsActivity; -import com.android.settings.overlay.FeatureFactory; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnAttach; -import com.android.settingslib.core.lifecycle.events.OnPause; -import com.android.settingslib.core.lifecycle.events.OnResume; - -import static com.android.settings.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN; - -/** - * Logs visibility change of a fragment. - */ -public class VisibilityLoggerMixin implements LifecycleObserver, OnResume, OnPause, OnAttach { - - private static final String TAG = "VisibilityLoggerMixin"; - - private final int mMetricsCategory; - - private MetricsFeatureProvider mMetricsFeature; - private int mSourceMetricsCategory = MetricsProto.MetricsEvent.VIEW_UNKNOWN; - private long mVisibleTimestamp; - - public VisibilityLoggerMixin(int metricsCategory) { - // MetricsFeature will be set during onAttach. - this(metricsCategory, null /* metricsFeature */); - } - - public VisibilityLoggerMixin(int metricsCategory, MetricsFeatureProvider metricsFeature) { - mMetricsCategory = metricsCategory; - mMetricsFeature = metricsFeature; - } - - @Override - public void onAttach(Context context) { - mMetricsFeature = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); - } - - @Override - public void onResume() { - mVisibleTimestamp = SystemClock.elapsedRealtime(); - if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) { - mMetricsFeature.visible(null /* context */, mSourceMetricsCategory, mMetricsCategory); - } - } - - @Override - public void onPause() { - mVisibleTimestamp = 0; - if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) { - mMetricsFeature.hidden(null /* context */, mMetricsCategory); - } - } - - /** - * Sets source metrics category for this logger. Source is the caller that opened this UI. - */ - public void setSourceMetricsCategory(Activity activity) { - if (mSourceMetricsCategory != MetricsProto.MetricsEvent.VIEW_UNKNOWN || activity == null) { - return; - } - final Intent intent = activity.getIntent(); - if (intent == null) { - return; - } - mSourceMetricsCategory = intent.getIntExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, - MetricsProto.MetricsEvent.VIEW_UNKNOWN); - } - - /** Returns elapsed time since onResume() */ - public long elapsedTimeSinceVisible() { - if (mVisibleTimestamp == 0) { - return 0; - } - return SystemClock.elapsedRealtime() - mVisibleTimestamp; - } -} diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java index 97eef1329d5..2d35ea78d33 100644 --- a/src/com/android/settings/dashboard/DashboardAdapter.java +++ b/src/com/android/settings/dashboard/DashboardAdapter.java @@ -41,7 +41,6 @@ import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.R.id; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardData.SuggestionConditionHeaderData; import com.android.settings.dashboard.conditional.Condition; import com.android.settings.dashboard.conditional.ConditionAdapter; @@ -50,6 +49,7 @@ import com.android.settings.dashboard.suggestions.SuggestionControllerMixin; import com.android.settings.dashboard.suggestions.SuggestionDismissController; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.Utils; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.Tile; diff --git a/src/com/android/settings/dashboard/DashboardAdapterV2.java b/src/com/android/settings/dashboard/DashboardAdapterV2.java index cc511c5f875..f98e8331adb 100644 --- a/src/com/android/settings/dashboard/DashboardAdapterV2.java +++ b/src/com/android/settings/dashboard/DashboardAdapterV2.java @@ -39,13 +39,13 @@ import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.R.id; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardDataV2.ConditionHeaderData; import com.android.settings.dashboard.conditional.Condition; import com.android.settings.dashboard.conditional.ConditionAdapterV2; import com.android.settings.dashboard.suggestions.SuggestionAdapterV2; import com.android.settings.dashboard.suggestions.SuggestionControllerMixin; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java index a06fee9fbc1..a14d9e9a76d 100644 --- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java @@ -41,8 +41,9 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.core.FeatureFlags; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.drawer.CategoryManager; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.ProfileSelectDialog; @@ -159,7 +160,8 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { pref.setFragment(clsName); } else if (tile.intent != null) { final Intent intent = new Intent(tile.intent); - intent.putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, sourceMetricsCategory); + intent.putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY, + sourceMetricsCategory); if (action != null) { intent.setAction(action); } @@ -208,7 +210,7 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { return; } final Intent intent = new Intent(tile.intent) - .putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, + .putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY, MetricsEvent.DASHBOARD_SUMMARY) .putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); diff --git a/src/com/android/settings/dashboard/conditional/Condition.java b/src/com/android/settings/dashboard/conditional/Condition.java index 05783bde798..d66440e9e89 100644 --- a/src/com/android/settings/dashboard/conditional/Condition.java +++ b/src/com/android/settings/dashboard/conditional/Condition.java @@ -24,8 +24,8 @@ import android.os.PersistableBundle; import android.support.annotation.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; public abstract class Condition { diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java index eb768e50d0e..d84aa7c9eac 100644 --- a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java +++ b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java @@ -27,13 +27,13 @@ import android.widget.Button; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardAdapter; import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder; import com.android.settings.dashboard.DashboardData; import com.android.settings.dashboard.DashboardData.HeaderMode; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.WirelessUtils; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.List; import java.util.Objects; diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java b/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java index 3f3e5c91daf..8db57f79678 100644 --- a/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java +++ b/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java @@ -27,10 +27,10 @@ import android.widget.Button; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.WirelessUtils; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.List; import java.util.Objects; diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java index fc1102901c0..2b79a9babfe 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java @@ -27,10 +27,10 @@ import android.view.ViewGroup; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder; import com.android.settings.dashboard.DashboardAdapter.IconCache; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.List; import java.util.Objects; diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java index 89c731f6aa4..56cd4529eab 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java @@ -31,10 +31,10 @@ import android.widget.LinearLayout; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder; import com.android.settings.dashboard.DashboardAdapterV2.IconCache; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java index fe19b958c2d..8cd1675ac2b 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java @@ -36,7 +36,6 @@ import com.android.settings.Settings.DoubleTapPowerSuggestionActivity; import com.android.settings.Settings.DoubleTwistSuggestionActivity; import com.android.settings.Settings.NightDisplaySuggestionActivity; import com.android.settings.Settings.SwipeToNotificationSuggestionActivity; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fingerprint.FingerprintEnrollSuggestionActivity; import com.android.settings.fingerprint.FingerprintSuggestionActivity; import com.android.settings.gestures.DoubleTapPowerPreferenceController; @@ -49,6 +48,7 @@ import com.android.settings.password.ScreenLockSuggestionActivity; import com.android.settings.support.NewDeviceIntroSuggestionActivity; import com.android.settings.wallpaper.WallpaperSuggestionActivity; import com.android.settings.wifi.WifiCallingSuggestionActivity; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.drawer.Tile; import java.util.List; diff --git a/src/com/android/settings/datausage/DataSaverBackend.java b/src/com/android/settings/datausage/DataSaverBackend.java index 041a81f06be..a0d388df1d0 100644 --- a/src/com/android/settings/datausage/DataSaverBackend.java +++ b/src/com/android/settings/datausage/DataSaverBackend.java @@ -25,8 +25,8 @@ import android.os.RemoteException; import android.util.SparseIntArray; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; diff --git a/src/com/android/settings/datetime/ZonePicker.java b/src/com/android/settings/datetime/ZonePicker.java index 57c340c6809..dc691275e31 100644 --- a/src/com/android/settings/datetime/ZonePicker.java +++ b/src/com/android/settings/datetime/ZonePicker.java @@ -35,8 +35,9 @@ import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; -import com.android.settings.core.instrumentation.Instrumentable; -import com.android.settings.core.instrumentation.VisibilityLoggerMixin; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.Instrumentable; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.datetime.ZoneGetter; import java.text.Collator; @@ -57,8 +58,7 @@ public class ZonePicker extends ListFragment implements Instrumentable { private static final int MENU_TIMEZONE = Menu.FIRST+1; private static final int MENU_ALPHABETICAL = Menu.FIRST; - private final VisibilityLoggerMixin mVisibilityLoggerMixin = - new VisibilityLoggerMixin(getMetricsCategory()); + private VisibilityLoggerMixin mVisibilityLoggerMixin; private boolean mSortedByTimezone; @@ -144,12 +144,6 @@ public class ZonePicker extends ListFragment implements Instrumentable { return -1; } - @Override - public void onAttach(Context context) { - super.onAttach(context); - mVisibilityLoggerMixin.onAttach(context); - } - @Override public int getMetricsCategory() { return MetricsProto.MetricsEvent.ZONE_PICKER; @@ -169,6 +163,13 @@ public class ZonePicker extends ListFragment implements Instrumentable { activity.setTitle(R.string.date_time_set_timezone); } + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(), + FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()); + } + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java index 8ab1a07fb13..a20afa1060a 100644 --- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java +++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java @@ -23,10 +23,10 @@ import android.provider.Settings; import android.support.v7.preference.Preference; import android.widget.Switch; -import com.android.internal.util.Preconditions; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; -import com.android.settings.widget.SwitchBar; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.util.Preconditions; +import com.android.settings.widget.SwitchBar; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; /** Handles the logic for flipping the storage management toggle on a {@link SwitchBar}. */ public class AutomaticStorageManagerSwitchBarController diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java index 2641f5d941f..0f3bfb8ec76 100644 --- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java +++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java @@ -34,11 +34,11 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnResume; diff --git a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java index 717d7650b75..8ab21b36fdb 100644 --- a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java @@ -25,12 +25,12 @@ import android.support.annotation.VisibleForTesting; import android.support.v7.preference.PreferenceScreen; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.deletionhelper.ActivationWarningFragment; import com.android.settings.widget.MasterSwitchController; import com.android.settings.widget.MasterSwitchPreference; import com.android.settings.widget.SwitchWidgetController; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnResume; diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java index 1149b99bce6..36232985934 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java @@ -38,11 +38,11 @@ import com.android.settings.Settings; import com.android.settings.Utils; import com.android.settings.applications.manageapplications.ManageApplications; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.deviceinfo.PrivateVolumeSettings.SystemInfoFragment; import com.android.settings.deviceinfo.StorageItemPreference; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.deviceinfo.StorageMeasurement; import com.android.settingslib.deviceinfo.StorageVolumeProvider; diff --git a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java index 68a21cebf9c..f3d17d58939 100644 --- a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java +++ b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java @@ -27,11 +27,11 @@ import android.support.v7.preference.Preference; import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.search.DatabaseIndexingUtils; import com.android.settings.search.InlineSwitchPayload; import com.android.settings.search.ResultPayload; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; public class AmbientDisplayNotificationsPreferenceController extends AbstractPreferenceController implements PreferenceControllerMixin, diff --git a/src/com/android/settings/display/AmbientDisplaySettings.java b/src/com/android/settings/display/AmbientDisplaySettings.java index 24aede05ef6..187325c0c7f 100644 --- a/src/com/android/settings/display/AmbientDisplaySettings.java +++ b/src/com/android/settings/display/AmbientDisplaySettings.java @@ -23,13 +23,13 @@ import android.provider.SearchIndexableResource; import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.gestures.DoubleTapScreenPreferenceController; import com.android.settings.gestures.PickupGesturePreferenceController; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import java.util.ArrayList; diff --git a/src/com/android/settings/display/AutoRotatePreferenceController.java b/src/com/android/settings/display/AutoRotatePreferenceController.java index c7f6af175a1..2134b882638 100644 --- a/src/com/android/settings/display/AutoRotatePreferenceController.java +++ b/src/com/android/settings/display/AutoRotatePreferenceController.java @@ -20,9 +20,9 @@ import android.support.v7.preference.TwoStatePreference; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.view.RotationPolicy; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; diff --git a/src/com/android/settings/display/ThemePreferenceController.java b/src/com/android/settings/display/ThemePreferenceController.java index d1341dd7435..9c1314ebc5e 100644 --- a/src/com/android/settings/display/ThemePreferenceController.java +++ b/src/com/android/settings/display/ThemePreferenceController.java @@ -29,9 +29,9 @@ import android.text.TextUtils; import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import libcore.util.Objects; diff --git a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java index c0347466812..a52433b374c 100644 --- a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java +++ b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java @@ -48,7 +48,6 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.ActionButtonPreference; import com.android.settings.wrapper.DevicePolicyManagerWrapper; @@ -56,6 +55,7 @@ import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnDestroy; diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java index 5d95dd2ec71..91f35e2533a 100644 --- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java +++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java @@ -49,10 +49,10 @@ import com.android.settings.SettingsActivity; import com.android.settings.core.FeatureFlags; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.Utils; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnDestroy; diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index ec54291e3ed..e0954e57f25 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -47,7 +47,6 @@ import com.android.settings.SettingsActivity; import com.android.settings.Utils; import com.android.settings.applications.LayoutPreference; import com.android.settings.applications.manageapplications.ManageApplications; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.display.AmbientDisplayPreferenceController; import com.android.settings.display.AutoBrightnessPreferenceController; @@ -61,6 +60,7 @@ import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import java.util.ArrayList; diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java b/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java index c50d5808629..605591dda15 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java @@ -54,7 +54,6 @@ import com.android.settings.SettingsActivity; import com.android.settings.Utils; import com.android.settings.applications.LayoutPreference; import com.android.settings.applications.manageapplications.ManageApplications; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.display.AmbientDisplayPreferenceController; import com.android.settings.display.AutoBrightnessPreferenceController; @@ -67,6 +66,7 @@ import com.android.settings.fuelgauge.anomaly.AnomalyLoader; import com.android.settings.fuelgauge.anomaly.AnomalySummaryPreferenceController; import com.android.settings.fuelgauge.anomaly.AnomalyUtils; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.AbstractPreferenceController; import java.util.ArrayList; diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java index 39d51dc08af..3dde95eff5b 100644 --- a/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java +++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java @@ -24,7 +24,6 @@ import android.util.SparseIntArray; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.os.BatteryStatsHelper; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fuelgauge.anomaly.action.AnomalyAction; import com.android.settings.fuelgauge.anomaly.action.ForceStopAction; import com.android.settings.fuelgauge.anomaly.action.LocationCheckAction; @@ -33,6 +32,7 @@ import com.android.settings.fuelgauge.anomaly.checker.AnomalyDetector; import com.android.settings.fuelgauge.anomaly.checker.BluetoothScanAnomalyDetector; import com.android.settings.fuelgauge.anomaly.checker.WakeLockAnomalyDetector; import com.android.settings.fuelgauge.anomaly.checker.WakeupAlarmAnomalyDetector; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java b/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java index 3ee89d1c4a2..d7de5a7ac2a 100644 --- a/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java +++ b/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java @@ -20,9 +20,9 @@ import android.content.Context; import android.util.Pair; import com.android.internal.logging.nano.MetricsProto; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; /** * Abstract class for anomaly action, which is triggered if we need to handle the anomaly diff --git a/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java b/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java index 9fa69fd02c0..1bf08b7b64d 100644 --- a/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java +++ b/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java @@ -18,7 +18,7 @@ package com.android.settings.fuelgauge.batterytip.actions; import android.content.Context; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; /** * Abstract class for battery tip action, which is triggered if we need to handle the battery tip diff --git a/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java b/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java index a19471e6d7b..cbd15812e5a 100644 --- a/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java +++ b/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java @@ -22,8 +22,8 @@ import android.support.v14.preference.PreferenceFragment; import com.android.settings.R; import com.android.settings.SettingsActivity; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fuelgauge.SmartBatterySettings; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; public class SmartBatteryAction extends BatteryTipAction { private SettingsActivity mSettingsActivity; diff --git a/src/com/android/settings/inputmethod/UserDictionarySettings.java b/src/com/android/settings/inputmethod/UserDictionarySettings.java index 9680af10c60..3bbc581ac82 100644 --- a/src/com/android/settings/inputmethod/UserDictionarySettings.java +++ b/src/com/android/settings/inputmethod/UserDictionarySettings.java @@ -42,10 +42,11 @@ import android.widget.SimpleCursorAdapter; import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.R; import com.android.settings.SettingsActivity; -import com.android.settings.core.instrumentation.Instrumentable; -import com.android.settings.core.instrumentation.VisibilityLoggerMixin; +import com.android.settingslib.core.instrumentation.Instrumentable; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; public class UserDictionarySettings extends ListFragment implements Instrumentable, LoaderManager.LoaderCallbacks { @@ -59,8 +60,7 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab private static final int OPTIONS_MENU_ADD = Menu.FIRST; private static final int LOADER_ID = 1; - private final VisibilityLoggerMixin mVisibilityLoggerMixin = - new VisibilityLoggerMixin(getMetricsCategory()); + private VisibilityLoggerMixin mVisibilityLoggerMixin; private Cursor mCursor; private String mLocale; @@ -70,16 +70,13 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab return MetricsProto.MetricsEvent.USER_DICTIONARY_SETTINGS; } - @Override - public void onAttach(Context context) { - super.onAttach(context); - mVisibilityLoggerMixin.onAttach(context); - } - @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(), + FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()); + final Intent intent = getActivity().getIntent(); final String localeFromIntent = null == intent ? null : intent.getStringExtra("locale"); diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java index 17cf211e9dd..0b771791be7 100644 --- a/src/com/android/settings/network/AirplaneModePreferenceController.java +++ b/src/com/android/settings/network/AirplaneModePreferenceController.java @@ -28,10 +28,10 @@ import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; import com.android.settings.AirplaneModeEnabler; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settings.R; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java index 4b1da310bdd..74c191006d4 100644 --- a/src/com/android/settings/network/NetworkDashboardFragment.java +++ b/src/com/android/settings/network/NetworkDashboardFragment.java @@ -31,13 +31,13 @@ import android.view.MenuInflater; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.network.MobilePlanPreferenceController.MobilePlanPreferenceHost; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.wifi.WifiMasterSwitchPreferenceController; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import java.util.ArrayList; diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java index 81ceca19c77..9180791fd55 100644 --- a/src/com/android/settings/notification/AbstractZenModePreferenceController.java +++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java @@ -34,9 +34,9 @@ import android.support.v7.preference.PreferenceScreen; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; diff --git a/src/com/android/settings/notification/ZenRulePreference.java b/src/com/android/settings/notification/ZenRulePreference.java index 71938732a2b..fee390f5edf 100644 --- a/src/com/android/settings/notification/ZenRulePreference.java +++ b/src/com/android/settings/notification/ZenRulePreference.java @@ -30,10 +30,10 @@ import android.view.View; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.utils.ManagedServiceSettings; import com.android.settings.utils.ZenServiceListing; import com.android.settingslib.TwoTargetPreference; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.Map; @@ -145,4 +145,4 @@ public class ZenRulePreference extends TwoTargetPreference { ? mContext.getResources().getString(R.string.switch_off_text) : mContext.getResources().getString(R.string.switch_on_text); } -} \ No newline at end of file +} diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java index dc9df8399f9..08057664c1c 100644 --- a/src/com/android/settings/overlay/FeatureFactory.java +++ b/src/com/android/settings/overlay/FeatureFactory.java @@ -24,7 +24,6 @@ import com.android.settings.R; import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.connecteddevice.SmsMirroringFeatureProvider; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.datausage.DataPlanFeatureProvider; @@ -36,6 +35,7 @@ import com.android.settings.security.SecurityFeatureProvider; import com.android.settings.search.SearchFeatureProvider; import com.android.settings.slices.SlicesFeatureProvider; import com.android.settings.users.UserFeatureProvider; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; /** * Abstract class for creating feature controllers. Allows OEM implementations to define their own diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java index 275ebb66865..f817d4bb218 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.java +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java @@ -29,7 +29,6 @@ import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.bluetooth.BluetoothFeatureProviderImpl; import com.android.settings.connecteddevice.SmsMirroringFeatureProvider; import com.android.settings.connecteddevice.SmsMirroringFeatureProviderImpl; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProviderImpl; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; @@ -55,6 +54,7 @@ import com.android.settings.users.UserFeatureProviderImpl; import com.android.settings.wrapper.ConnectivityManagerWrapper; import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settings.wrapper.IPackageManagerWrapper; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.wrapper.PackageManagerWrapper; /** diff --git a/src/com/android/settings/widget/SwitchBar.java b/src/com/android/settings/widget/SwitchBar.java index 749ec0a919b..3be5eca3c2e 100644 --- a/src/com/android/settings/widget/SwitchBar.java +++ b/src/com/android/settings/widget/SwitchBar.java @@ -39,9 +39,9 @@ import android.widget.Switch; import android.widget.TextView; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java index 9c431422371..c5e79b2db49 100644 --- a/src/com/android/settings/wifi/WifiEnabler.java +++ b/src/com/android/settings/wifi/WifiEnabler.java @@ -33,9 +33,9 @@ import android.widget.Toast; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.widget.SwitchWidgetController; import com.android.settings.wrapper.ConnectivityManagerWrapper; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.WirelessUtils; diff --git a/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java b/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java index de1b030f3dc..8843d93775a 100644 --- a/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java +++ b/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java @@ -19,12 +19,12 @@ import android.content.Context; import android.support.v7.preference.PreferenceScreen; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.R; import com.android.settings.widget.SummaryUpdater; import com.android.settings.widget.MasterSwitchPreference; import com.android.settings.widget.MasterSwitchController; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index 70ee20de03d..13ffd5bee44 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -54,7 +54,6 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.applications.LayoutPreference; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.widget.ActionButtonPreference; import com.android.settings.widget.EntityHeaderController; import com.android.settings.wifi.WifiDetailPreference; @@ -63,6 +62,7 @@ import com.android.settings.wifi.WifiDialog.WifiDialogListener; import com.android.settings.wifi.WifiUtils; import com.android.settings.wrapper.ConnectivityManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; diff --git a/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java b/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java index 942634a0a71..3a7d094747f 100644 --- a/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java @@ -17,6 +17,7 @@ package com.android.settings; import android.app.Dialog; import android.app.Fragment; +import android.content.Context; import org.junit.Before; import org.junit.Test; @@ -38,6 +39,8 @@ public class SettingsDialogFragmentTest { private static final int DIALOG_ID = 15; + @Mock + private Context mContext; @Mock private DialogCreatableFragment mDialogCreatable; private SettingsPreferenceFragment.SettingsDialogFragment mDialogFragment; @@ -53,9 +56,10 @@ public class SettingsDialogFragmentTest { mDialogFragment = new SettingsPreferenceFragment.SettingsDialogFragment(mDialogCreatable, DIALOG_ID); + mDialogFragment.onAttach(mContext); mDialogFragment.getMetricsCategory(); - // getDialogMetricsCategory called in constructor, and explicitly in test. + // getDialogMetricsCategory called in onAttach, and explicitly in test. verify(mDialogCreatable, times(2)).getDialogMetricsCategory(DIALOG_ID); } @@ -66,6 +70,7 @@ public class SettingsDialogFragmentTest { try { mDialogFragment = new SettingsPreferenceFragment.SettingsDialogFragment( mDialogCreatable, DIALOG_ID); + mDialogFragment.onAttach(mContext); } catch (IllegalStateException e) { // getDialogMetricsCategory called in constructor verify(mDialogCreatable).getDialogMetricsCategory(DIALOG_ID); diff --git a/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java index 5c0badcc475..f85d43aac6a 100644 --- a/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java @@ -42,9 +42,9 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java index e9d37f6a0c2..71020be315a 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java @@ -32,11 +32,11 @@ import android.os.UserManager; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java index b973edb674d..828b5a17335 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java @@ -29,13 +29,13 @@ import android.widget.Switch; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.widget.MasterSwitchController; import com.android.settings.widget.MasterSwitchPreference; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.BeforeClass; diff --git a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java index 8666ce3c13c..c3b22b3a98c 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java @@ -26,11 +26,11 @@ import android.content.Context; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java index 4455549db12..867b5df7336 100644 --- a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java +++ b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java @@ -20,6 +20,7 @@ import android.app.Fragment; import android.util.ArraySet; import com.android.settings.core.codeinspection.CodeInspector; +import com.android.settingslib.core.instrumentation.Instrumentable; import java.util.ArrayList; import java.util.List; diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java index 9e37896fa62..8ad2d696846 100644 --- a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java @@ -21,6 +21,7 @@ import android.os.Bundle; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java index da48f15c4c4..2950c072ad6 100644 --- a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java +++ b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java @@ -31,6 +31,9 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.TestConfig; import com.android.settings.overlay.FeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.core.instrumentation.LogWriter; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import org.junit.Before; import org.junit.Test; @@ -58,7 +61,6 @@ public class MetricsFeatureProviderTest { @Mock private VisibilityLoggerMixin mockVisibilityLogger; private Context mContext; - private MetricsFeatureProvider mProvider; @Captor private ArgumentCaptor mPairCaptor; @@ -67,12 +69,6 @@ public class MetricsFeatureProviderTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; - mProvider = new MetricsFeatureProvider(); - List writers = new ArrayList<>(); - writers.add(mockLogWriter); - ReflectionHelpers.setField(mProvider, "mLoggerWriters", writers); - - when(mockVisibilityLogger.elapsedTimeSinceVisible()).thenReturn(ELAPSED_TIME); } @Test @@ -84,60 +80,4 @@ public class MetricsFeatureProviderTest { assertThat(feature1 == feature2).isTrue(); } - - @Test - public void logDashboardStartIntent_intentEmpty_shouldNotLog() { - mProvider.logDashboardStartIntent(mContext, null /* intent */, - MetricsEvent.SETTINGS_GESTURES); - - verifyNoMoreInteractions(mockLogWriter); - } - - @Test - public void logDashboardStartIntent_intentHasNoComponent_shouldLog() { - final Intent intent = new Intent(Intent.ACTION_ASSIST); - - mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES); - - verify(mockLogWriter).action( - eq(mContext), - eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK), - anyString(), - eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES))); - } - - @Test - public void logDashboardStartIntent_intentIsExternal_shouldLog() { - final Intent intent = new Intent().setComponent(new ComponentName("pkg", "cls")); - - mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES); - - verify(mockLogWriter).action( - eq(mContext), - eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK), - anyString(), - eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES))); - } - - @Test - public void action_BooleanLogsElapsedTime() { - mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_BOOLEAN); - verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_BOOLEAN), mPairCaptor.capture()); - - Pair value = mPairCaptor.getValue(); - assertThat(value.first instanceof Integer).isTrue(); - assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS); - assertThat(value.second).isEqualTo(ELAPSED_TIME); - } - - @Test - public void action_IntegerLogsElapsedTime() { - mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_INTEGER); - verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_INTEGER), mPairCaptor.capture()); - - Pair value = mPairCaptor.getValue(); - assertThat(value.first instanceof Integer).isTrue(); - assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS); - assertThat(value.second).isEqualTo(ELAPSED_TIME); - } } diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java deleted file mode 100644 index c80e3a89d8d..00000000000 --- a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.settings.core.instrumentation; - -import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE; -import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE; -import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE; -import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.content.Context; -import android.content.SharedPreferences; -import android.util.Pair; - -import com.android.settings.TestConfig; -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import com.google.common.truth.Platform; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.ArgumentMatcher; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class SharedPreferenceLoggerTest { - - private static final String TEST_TAG = "tag"; - private static final String TEST_KEY = "key"; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Context mContext; - - private ArgumentMatcher> mNamePairMatcher; - private FakeFeatureFactory mFactory; - private MetricsFeatureProvider mMetricsFeature; - private SharedPreferencesLogger mSharedPrefLogger; - - @Before - public void init() { - MockitoAnnotations.initMocks(this); - mFactory = FakeFeatureFactory.setupForTest(); - mMetricsFeature = mFactory.metricsFeatureProvider; - - mSharedPrefLogger = new SharedPreferencesLogger(mContext, TEST_TAG); - mNamePairMatcher = pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, String.class); - } - - @Test - public void putInt_shouldNotLogInitialPut() { - final SharedPreferences.Editor editor = mSharedPrefLogger.edit(); - editor.putInt(TEST_KEY, 1); - editor.putInt(TEST_KEY, 1); - editor.putInt(TEST_KEY, 1); - editor.putInt(TEST_KEY, 2); - editor.putInt(TEST_KEY, 2); - editor.putInt(TEST_KEY, 2); - editor.putInt(TEST_KEY, 2); - - verify(mMetricsFeature, times(6)).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.class))); - } - - @Test - public void putBoolean_shouldNotLogInitialPut() { - final SharedPreferences.Editor editor = mSharedPrefLogger.edit(); - editor.putBoolean(TEST_KEY, true); - editor.putBoolean(TEST_KEY, true); - editor.putBoolean(TEST_KEY, false); - editor.putBoolean(TEST_KEY, false); - editor.putBoolean(TEST_KEY, false); - - - verify(mMetricsFeature).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, true))); - verify(mMetricsFeature, times(3)).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, false))); - } - - @Test - public void putLong_shouldNotLogInitialPut() { - final SharedPreferences.Editor editor = mSharedPrefLogger.edit(); - editor.putLong(TEST_KEY, 1); - editor.putLong(TEST_KEY, 1); - editor.putLong(TEST_KEY, 1); - editor.putLong(TEST_KEY, 1); - editor.putLong(TEST_KEY, 2); - - verify(mMetricsFeature, times(4)).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.class))); - } - - @Test - public void putLong_biggerThanIntMax_shouldLogIntMax() { - final SharedPreferences.Editor editor = mSharedPrefLogger.edit(); - final long veryBigNumber = 500L + Integer.MAX_VALUE; - editor.putLong(TEST_KEY, 1); - editor.putLong(TEST_KEY, veryBigNumber); - - verify(mMetricsFeature).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches( - FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.MAX_VALUE))); - } - - @Test - public void putLong_smallerThanIntMin_shouldLogIntMin() { - final SharedPreferences.Editor editor = mSharedPrefLogger.edit(); - final long veryNegativeNumber = -500L + Integer.MIN_VALUE; - editor.putLong(TEST_KEY, 1); - editor.putLong(TEST_KEY, veryNegativeNumber); - - verify(mMetricsFeature).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches( - FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.MIN_VALUE))); - } - - @Test - public void putFloat_shouldNotLogInitialPut() { - final SharedPreferences.Editor editor = mSharedPrefLogger.edit(); - editor.putFloat(TEST_KEY, 1); - editor.putFloat(TEST_KEY, 1); - editor.putFloat(TEST_KEY, 1); - editor.putFloat(TEST_KEY, 1); - editor.putFloat(TEST_KEY, 2); - - verify(mMetricsFeature, times(4)).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE, Float.class))); - } - - @Test - public void logPackage_shouldUseLogPackageApi() { - mSharedPrefLogger.logPackageName("key", "com.android.settings"); - verify(mMetricsFeature).action(any(Context.class), - eq(ACTION_SETTINGS_PREFERENCE_CHANGE), - eq("com.android.settings"), - any(Pair.class)); - } - - private ArgumentMatcher> pairMatches(int tag, Class clazz) { - return pair -> pair.first == tag && Platform.isInstanceOfType(pair.second, clazz); - } - - private ArgumentMatcher> pairMatches(int tag, boolean bool) { - return pair -> pair.first == tag - && Platform.isInstanceOfType(pair.second, Integer.class) - && pair.second.equals((bool ? 1 : 0)); - } - - private ArgumentMatcher> pairMatches(int tag, int val) { - return pair -> pair.first == tag - && Platform.isInstanceOfType(pair.second, Integer.class) - && pair.second.equals(val); - } -} diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java deleted file mode 100644 index 1a47a66f25e..00000000000 --- a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.settings.core.instrumentation; - -import static com.android.settings.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN; - -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; - -import com.android.internal.logging.nano.MetricsProto; -import com.android.settings.SettingsActivity; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.TestConfig; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; - - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class VisibilityLoggerMixinTest { - - @Mock - private MetricsFeatureProvider mMetricsFeature; - - private VisibilityLoggerMixin mMixin; - - @Before - public void init() { - MockitoAnnotations.initMocks(this); - mMixin = new VisibilityLoggerMixin(TestInstrumentable.TEST_METRIC, mMetricsFeature); - } - - @Test - public void shouldLogVisibleOnResume() { - mMixin.onResume(); - - verify(mMetricsFeature, times(1)) - .visible(nullable(Context.class), eq(MetricsProto.MetricsEvent.VIEW_UNKNOWN), - eq(TestInstrumentable.TEST_METRIC)); - } - - @Test - public void shouldLogVisibleWithSource() { - final Intent sourceIntent = new Intent() - .putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, - MetricsProto.MetricsEvent.SETTINGS_GESTURES); - final Activity activity = mock(Activity.class); - when(activity.getIntent()).thenReturn(sourceIntent); - mMixin.setSourceMetricsCategory(activity); - mMixin.onResume(); - - verify(mMetricsFeature, times(1)) - .visible(nullable(Context.class), eq(MetricsProto.MetricsEvent.SETTINGS_GESTURES), - eq(TestInstrumentable.TEST_METRIC)); - } - - @Test - public void shouldLogHideOnPause() { - mMixin.onPause(); - - verify(mMetricsFeature, times(1)) - .hidden(nullable(Context.class), eq(TestInstrumentable.TEST_METRIC)); - } - - @Test - public void shouldNotLogIfMetricsFeatureIsNull() { - mMixin = new VisibilityLoggerMixin(TestInstrumentable.TEST_METRIC); - mMixin.onResume(); - mMixin.onPause(); - - verify(mMetricsFeature, never()) - .hidden(nullable(Context.class), anyInt()); - } - - @Test - public void shouldNotLogIfMetricsCategoryIsUnknown() { - mMixin = new VisibilityLoggerMixin(METRICS_CATEGORY_UNKNOWN, mMetricsFeature); - - mMixin.onResume(); - mMixin.onPause(); - - verify(mMetricsFeature, never()) - .hidden(nullable(Context.class), anyInt()); - } - - private final class TestInstrumentable implements Instrumentable { - - public static final int TEST_METRIC = 12345; - - @Override - public int getMetricsCategory() { - return TEST_METRIC; - } - } -} diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java index 741f2bc084c..afa914cf93f 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java @@ -51,6 +51,7 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settings.testutils.shadow.ShadowTileUtils; import com.android.settings.testutils.shadow.ShadowUserManager; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.CategoryManager; import com.android.settingslib.drawer.DashboardCategory; @@ -372,7 +373,7 @@ public class DashboardFeatureProviderImplTest { final Intent launchIntent = shadowActivity.getNextStartedActivityForResult().intent; assertThat(launchIntent.getAction()) .isEqualTo("TestAction"); - assertThat(launchIntent.getIntExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, 0)) + assertThat(launchIntent.getIntExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY, 0)) .isEqualTo(MetricsProto.MetricsEvent.SETTINGS_GESTURES); } diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java index 6c663ab6cef..40e590a665c 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java @@ -33,10 +33,10 @@ import android.support.v7.preference.PreferenceScreen; import com.android.settings.TestConfig; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.instrumentation.VisibilityLoggerMixin; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.Tile; import com.android.settingslib.drawer.TileUtils; diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java index d077e6fcd77..1a3fa5e7092 100644 --- a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java @@ -22,7 +22,7 @@ import android.graphics.drawable.Icon; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java index 9ab88d3a805..8b3c7708230 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java @@ -60,6 +60,7 @@ public class DataUsageListTest { @Test public void resumePause_shouldListenUnlistenDataStateChange() { + mDataUsageList.onAttach(mContext); mDataUsageList.onResume(); verify(mListener).setListener(true, 0, mContext); diff --git a/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java b/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java index 92807e9fcf3..9f6d0ef984a 100644 --- a/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java +++ b/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java @@ -28,8 +28,8 @@ import android.view.ViewGroup; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.VisibilityLoggerMixin; import com.android.settings.testutils.shadow.ShadowZoneGetter; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java index 66ccc6ec3dd..ab32fa28705 100644 --- a/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java +++ b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java @@ -31,11 +31,11 @@ import android.support.v7.preference.Preference; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; import com.android.settings.widget.SwitchBar; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java index 90ce3953ee3..9c566113149 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java @@ -37,13 +37,13 @@ import android.support.v7.preference.PreferenceScreen; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.os.RoSystemProperties; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.deletionhelper.ActivationWarningFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; import com.android.settings.widget.MasterSwitchPreference; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.After; import org.junit.Before; diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java index 1a3139d509c..2da756f5a1d 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java @@ -50,13 +50,13 @@ import com.android.settings.SettingsActivity; import com.android.settings.SubSettings; import com.android.settings.TestConfig; import com.android.settings.applications.manageapplications.ManageApplications; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.deviceinfo.PrivateVolumeSettings; import com.android.settings.deviceinfo.StorageItemPreference; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settingslib.applications.StorageStatsSource; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.deviceinfo.StorageVolumeProvider; import org.junit.After; diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java index 6ad37ce2cec..e251be0db6b 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java @@ -38,10 +38,10 @@ import android.widget.LinearLayout; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.deviceinfo.StorageVolumeProvider; import org.junit.After; diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java index e1ce6945c13..c003f176613 100644 --- a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java @@ -32,11 +32,11 @@ import android.support.v14.preference.SwitchPreference; import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.search.InlinePayload; import com.android.settings.search.InlineSwitchPayload; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowSecureSettings; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java index c590fd34dc1..5418ead24d4 100644 --- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java +++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java @@ -36,6 +36,7 @@ import android.widget.TextView; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.password.ChooseLockSettingsHelper; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowUtils; import com.android.settings.testutils.shadow.ShadowVibrator; @@ -69,12 +70,15 @@ public class FingerprintEnrollEnrollingTest { private FingerprintEnrollEnrolling mActivity; + private FakeFeatureFactory mFactory; + @Before public void setUp() { MockitoAnnotations.initMocks(this); ShadowUtils.setFingerprintManager(mFingerprintManager); ShadowVibrator.addToServiceMap(); + mFactory = FakeFeatureFactory.setupForTest(); mActivity = Robolectric.buildActivity( FingerprintEnrollEnrolling.class, new Intent() diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java index d495b74e903..be53aa57487 100644 --- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java +++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java @@ -33,6 +33,7 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.password.ChooseLockSettingsHelper; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.ShadowEventLogWriter; @@ -69,10 +70,13 @@ public class FingerprintEnrollFindSensorTest { private FingerprintEnrollFindSensor mActivity; + private FakeFeatureFactory mFactory; + @Before public void setUp() { MockitoAnnotations.initMocks(this); ShadowUtils.setFingerprintManager(mFingerprintManager); + mFactory = FakeFeatureFactory.setupForTest(); mActivity = Robolectric.buildActivity( FingerprintEnrollFindSensor.class, diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java index 0254bcb997b..f52f437414b 100644 --- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java +++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java @@ -30,6 +30,7 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowEventLogWriter; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; @@ -63,9 +64,12 @@ public class FingerprintSuggestionActivityTest { private ActivityController mController; + private FakeFeatureFactory mFactory; + @Before public void setUp() { MockitoAnnotations.initMocks(this); + mFactory = FakeFeatureFactory.setupForTest(); final Intent intent = new Intent(); mController = Robolectric.buildActivity(FingerprintSuggestionActivity.class, intent); diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java index c3899e9b01d..c786608386a 100644 --- a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java +++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java @@ -27,6 +27,7 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.password.ChooseLockSettingsHelper; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.ShadowEventLogWriter; @@ -61,10 +62,13 @@ public class SetupFingerprintEnrollFindSensorTest { private SetupFingerprintEnrollFindSensor mActivity; + private FakeFeatureFactory mFactory; + @Before public void setUp() { MockitoAnnotations.initMocks(this); ShadowUtils.setFingerprintManager(mFingerprintManager); + mFactory = FakeFeatureFactory.setupForTest(); } private void createActivity(Intent intent) { diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java index 2d98bf44511..f5b0c8a9ad0 100644 --- a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java +++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java @@ -35,6 +35,7 @@ import com.android.settings.fingerprint.SetupFingerprintEnrollIntroductionTest import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment; import com.android.settings.password.SetupSkipDialog; import com.android.settings.password.StorageManagerWrapper; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowEventLogWriter; import com.android.settings.testutils.shadow.ShadowFingerprintManager; @@ -72,6 +73,7 @@ public class SetupFingerprintEnrollIntroductionTest { @Mock private UserInfo mUserInfo; + private FakeFeatureFactory mFactory; private ActivityController mController; @@ -83,6 +85,8 @@ public class SetupFingerprintEnrollIntroductionTest { .setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true); ShadowFingerprintManager.addToServiceMap(); + mFactory = FakeFeatureFactory.setupForTest(); + final Intent intent = new Intent(); mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java index 38391c9350b..3e33823b82c 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java @@ -24,7 +24,6 @@ import android.os.Build; import android.util.Pair; import com.android.internal.logging.nano.MetricsProto; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fuelgauge.anomaly.action.StopAndBackgroundCheckAction; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; @@ -32,6 +31,7 @@ import com.android.settings.fuelgauge.anomaly.action.ForceStopAction; import com.android.settings.fuelgauge.anomaly.checker.WakeLockAnomalyDetector; import com.android.settings.testutils.shadow.ShadowKeyValueListParserWrapperImpl; import com.android.settings.fuelgauge.anomaly.checker.WakeupAlarmAnomalyDetector; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java index 1ee52ca463c..737c16d5001 100644 --- a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java +++ b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java @@ -20,6 +20,7 @@ import android.content.Context; import android.view.View; import android.widget.TextView; import com.android.settings.TestConfig; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowSettingsPreferenceFragment; @@ -27,6 +28,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; @@ -39,6 +41,11 @@ public class LocaleListEditorTest { private LocaleListEditor mLocaleListEditor; + @Mock + private Context mContext; + + private FakeFeatureFactory mFactory; + @Before public void setUp() { mLocaleListEditor = new LocaleListEditor(); @@ -48,11 +55,13 @@ public class LocaleListEditorTest { RuntimeEnvironment.application.getSystemService(Context.RESTRICTIONS_SERVICE)); ReflectionHelpers.setField(mLocaleListEditor, "mUserManager", RuntimeEnvironment.application.getSystemService(Context.USER_SERVICE)); + mFactory = FakeFeatureFactory.setupForTest(); } @Test public void testDisallowConfigLocale_unrestrict() { ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", true); + mLocaleListEditor.onAttach(mContext); mLocaleListEditor.onResume(); Assert.assertEquals(View.GONE, mLocaleListEditor.getEmptyTextView().getVisibility()); } @@ -60,6 +69,7 @@ public class LocaleListEditorTest { @Test public void testDisallowConfigLocale_restrict() { ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", false); + mLocaleListEditor.onAttach(mContext); mLocaleListEditor.onResume(); Assert.assertEquals(View.VISIBLE, mLocaleListEditor.getEmptyTextView().getVisibility()); } diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java index fb2b62e7413..b4592b8c7f2 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -24,7 +24,6 @@ import android.content.Context; import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.connecteddevice.SmsMirroringFeatureProvider; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.datausage.DataPlanFeatureProvider; @@ -39,6 +38,7 @@ import com.android.settings.search.SearchFeatureProvider; import com.android.settings.security.SecurityFeatureProvider; import com.android.settings.slices.SlicesFeatureProvider; import com.android.settings.users.UserFeatureProvider; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.mockito.Answers; diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java index dcced4e40d0..9caf09f3e8d 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java @@ -19,7 +19,7 @@ package com.android.settings.testutils.shadow; import android.content.Context; -import com.android.settings.core.instrumentation.EventLogWriter; +import com.android.settingslib.core.instrumentation.EventLogWriter; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; diff --git a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java index e44be0e8781..59a08ae8801 100644 --- a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java +++ b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java @@ -44,10 +44,10 @@ import android.os.UserManager; import com.android.settings.TestConfig; import com.android.settings.applications.defaultapps.DefaultAppInfo; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.widget.RadioButtonPreference; import com.android.settings.wrapper.UserPackageWrapper; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; diff --git a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java index 63f89e62c5c..84549a62388 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java @@ -22,9 +22,9 @@ import android.net.wifi.WifiManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.widget.SwitchWidgetController; import com.android.settings.wrapper.ConnectivityManagerWrapper; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java index 1708e364e0f..82569c74054 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java @@ -30,10 +30,10 @@ import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.PreferenceScreen; import com.android.settings.TestConfig; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.widget.MasterSwitchPreference; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java index 4f774357612..ca2cac09257 100644 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java @@ -65,7 +65,6 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.applications.LayoutPreference; -import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowBidiFormatter; import com.android.settings.testutils.shadow.ShadowDevicePolicyManagerWrapper; @@ -76,6 +75,7 @@ import com.android.settings.widget.ActionButtonPreferenceTest; import com.android.settings.widget.EntityHeaderController; import com.android.settings.wifi.WifiDetailPreference; import com.android.settings.wrapper.ConnectivityManagerWrapper; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.wifi.AccessPoint; From 964b36d415048eb4fb2d03e887a0db813b7b6e1a Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Thu, 18 Jan 2018 11:36:21 -0800 Subject: [PATCH 15/30] Update suggestion card layout - set card corner radius - update card margin according to number of card and card position - update text alignment for title and summary Bug: 70573674 Test: visual Change-Id: Icfceed5614ded97ce2a7767667ae97f92b89b2fa --- res/layout/suggestion_container.xml | 2 - res/layout/suggestion_tile_v2.xml | 19 +++-- res/layout/suggestion_tile_with_button_v2.xml | 20 +++-- res/values/dimens.xml | 8 +- res/values/styles.xml | 9 +++ .../dashboard/DashboardAdapterV2.java | 3 +- .../suggestions/SuggestionAdapterV2.java | 78 ++++++++++++++----- 7 files changed, 99 insertions(+), 40 deletions(-) diff --git a/res/layout/suggestion_container.xml b/res/layout/suggestion_container.xml index 2aa104333db..e01a5903c79 100644 --- a/res/layout/suggestion_container.xml +++ b/res/layout/suggestion_container.xml @@ -57,8 +57,6 @@ android:layout_height="wrap_content" android:paddingTop="20dp" android:paddingBottom="16dp" - android:paddingStart="16dp" - android:paddingEnd="16dp" android:scrollbars="none"/> diff --git a/res/layout/suggestion_tile_v2.xml b/res/layout/suggestion_tile_v2.xml index e180897af06..27b3c349e9e 100644 --- a/res/layout/suggestion_tile_v2.xml +++ b/res/layout/suggestion_tile_v2.xml @@ -21,7 +21,8 @@ android:layout_width="328dp" android:layout_height="wrap_content" app:cardUseCompatPadding="true" - app:cardElevation="2dp"> + app:cardElevation="2dp" + app:cardCornerRadius="@dimen/suggestion_card_corner_radius"> @@ -55,21 +56,23 @@ diff --git a/res/layout/suggestion_tile_with_button_v2.xml b/res/layout/suggestion_tile_with_button_v2.xml index 01be23658fc..5f4ed18bab3 100644 --- a/res/layout/suggestion_tile_with_button_v2.xml +++ b/res/layout/suggestion_tile_with_button_v2.xml @@ -21,14 +21,14 @@ android:layout_width="328dp" android:layout_height="wrap_content" app:cardUseCompatPadding="true" - app:cardElevation="2dp"> + app:cardElevation="2dp" + app:cardCornerRadius="@dimen/suggestion_card_corner_radius"> + android:orientation="vertical"> @@ -56,9 +56,11 @@