Log visibility change for DialogCreatable in Settings.

Bug: 30681529
Test: adb logcat -b events | egrep "(sysui_|notification_)"
Test: make RunSettingsRoboTests
Change-Id: I51754d258ba1ddfae24323681f21cd02de4dbb4e
This commit is contained in:
Fan Zhang
2016-09-19 17:45:24 -07:00
parent 4b2406f3f3
commit d65184faef
19 changed files with 307 additions and 6 deletions

View File

@@ -507,4 +507,12 @@ public class ApnSettings extends RestrictedSettingsFragment implements
} }
return null; return null;
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
if (dialogId == DIALOG_RESTORE_DEFAULTAPN) {
return MetricsEvent.DIALOG_APN_RESTORE_DEFAULT;
}
return 0;
}
} }

View File

@@ -26,4 +26,6 @@ import android.app.Dialog;
public interface DialogCreatable { public interface DialogCreatable {
Dialog onCreateDialog(int dialogId); Dialog onCreateDialog(int dialogId);
int getDialogMetricsCategory(int dialogId);
} }

View File

@@ -183,6 +183,14 @@ public class DreamSettings extends SettingsPreferenceFragment implements
return super.onCreateDialog(dialogId); return super.onCreateDialog(dialogId);
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
if (dialogId == DIALOG_WHEN_TO_DREAM) {
return MetricsEvent.DIALOG_DREAM_START_DELAY;
}
return 0;
}
private Dialog createWhenToDreamDialog() { private Dialog createWhenToDreamDialog() {
final CharSequence[] items = { final CharSequence[] items = {
mContext.getString(R.string.screensaver_settings_summary_dock), mContext.getString(R.string.screensaver_settings_summary_dock),

View File

@@ -259,6 +259,14 @@ public class EncryptionInterstitial extends SettingsActivity {
} }
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
if (dialogId == ACCESSIBILITY_WARNING_DIALOG) {
return MetricsEvent.DIALOG_ENCRYPTION_INTERSTITIAL_ACCESSIBILITY;
}
return 0;
}
private void setRequirePasswordState(boolean required) { private void setRequirePasswordState(boolean required) {
mPasswordRequired = required; mPasswordRequired = required;
} }

View File

@@ -108,6 +108,11 @@ public class ProxySelector extends InstrumentedFragment implements DialogCreatab
return null; return null;
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
return MetricsEvent.DIALOG_PROXY_SELECTOR_ERROR;
}
private void showDialog(int dialogId) { private void showDialog(int dialogId) {
if (mDialogFragment != null) { if (mDialogFragment != null) {
Log.e(TAG, "Old dialog fragment not null!"); Log.e(TAG, "Old dialog fragment not null!");

View File

@@ -46,9 +46,11 @@ import android.widget.Button;
import com.android.settings.applications.LayoutPreference; import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.InstrumentedFragment;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.HelpUtils; import com.android.settingslib.HelpUtils;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Base class for Settings fragments, with some helper functions and dialog management. * Base class for Settings fragments, with some helper functions and dialog management.
@@ -501,10 +503,16 @@ public abstract class SettingsPreferenceFragment extends InstrumentedFragment
mDialogFragment.show(getChildFragmentManager(), Integer.toString(dialogId)); mDialogFragment.show(getChildFragmentManager(), Integer.toString(dialogId));
} }
@Override
public Dialog onCreateDialog(int dialogId) { public Dialog onCreateDialog(int dialogId) {
return null; return null;
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
return 0;
}
protected void removeDialog(int dialogId) { protected void removeDialog(int dialogId) {
// mDialogFragment may not be visible yet in parent fragment's onResume(). // mDialogFragment may not be visible yet in parent fragment's onResume().
// To be able to dismiss dialog at that time, don't check // To be able to dismiss dialog at that time, don't check
@@ -569,12 +577,10 @@ public abstract class SettingsPreferenceFragment extends InstrumentedFragment
onDialogShowing(); onDialogShowing();
} }
public static class SettingsDialogFragment extends DialogFragment { public static class SettingsDialogFragment extends InstrumentedDialogFragment {
private static final String KEY_DIALOG_ID = "key_dialog_id"; private static final String KEY_DIALOG_ID = "key_dialog_id";
private static final String KEY_PARENT_FRAGMENT_ID = "key_parent_fragment_id"; private static final String KEY_PARENT_FRAGMENT_ID = "key_parent_fragment_id";
private int mDialogId;
private Fragment mParentFragment; private Fragment mParentFragment;
private DialogInterface.OnCancelListener mOnCancelListener; private DialogInterface.OnCancelListener mOnCancelListener;
@@ -585,7 +591,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedFragment
} }
public SettingsDialogFragment(DialogCreatable fragment, int dialogId) { public SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
mDialogId = dialogId; super(fragment, dialogId);
if (!(fragment instanceof Fragment)) { if (!(fragment instanceof Fragment)) {
throw new IllegalArgumentException("fragment argument must be an instance of " throw new IllegalArgumentException("fragment argument must be an instance of "
+ Fragment.class.getName()); + Fragment.class.getName());
@@ -593,6 +599,16 @@ public abstract class SettingsPreferenceFragment extends InstrumentedFragment
mParentFragment = (Fragment) fragment; mParentFragment = (Fragment) fragment;
} }
@Override
public int getMetricsCategory() {
final int metricsCategory = mDialogCreatable.getDialogMetricsCategory(mDialogId);
if (metricsCategory <= 0) {
throw new IllegalStateException("Dialog must provide a metrics category");
}
return metricsCategory;
}
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);

View File

@@ -259,6 +259,14 @@ public class TetherSettings extends RestrictedSettingsFragment
return null; return null;
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
if (dialogId == DIALOG_AP_SETTINGS) {
return MetricsEvent.DIALOG_AP_SETTINGS;
}
return 0;
}
private class TetherChangeReceiver extends BroadcastReceiver { private class TetherChangeReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context content, Intent intent) { public void onReceive(Context content, Intent intent) {

View File

@@ -202,6 +202,15 @@ public class ToggleAccessibilityServicePreferenceFragment
} }
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
if (dialogId == DIALOG_ID_ENABLE_WARNING) {
return MetricsEvent.DIALOG_ACCESSIBILITY_SERVICE_ENABLE;
} else {
return MetricsEvent.DIALOG_ACCESSIBILITY_SERVICE_DISABLE;
}
}
private void updateSwitchBarToggleSwitch() { private void updateSwitchBarToggleSwitch() {
final boolean checked = AccessibilityUtils.getEnabledServicesFromSettings(getActivity()) final boolean checked = AccessibilityUtils.getEnabledServicesFromSettings(getActivity())
.contains(mComponentName); .contains(mComponentName);

View File

@@ -52,13 +52,13 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.collect.Lists;
import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils;
import com.google.android.collect.Lists;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@@ -152,6 +152,20 @@ public class AccountSyncSettings extends AccountPreferenceBase {
return MetricsEvent.ACCOUNTS_ACCOUNT_SYNC; return MetricsEvent.ACCOUNTS_ACCOUNT_SYNC;
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) {
case REALLY_REMOVE_DIALOG:
return MetricsEvent.DIALOG_ACCOUNT_SYNC_REMOVE;
case FAILED_REMOVAL_DIALOG:
return MetricsEvent.DIALOG_ACCOUNT_SYNC_FAILED_REMOVAL;
case CANT_DO_ONETIME_SYNC_DIALOG:
return MetricsEvent.DIALOG_ACCOUNT_SYNC_CANNOT_ONETIME_SYNC;
default:
return 0;
}
}
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);

View File

@@ -15,12 +15,25 @@
*/ */
package com.android.settings.core.instrumentation; package com.android.settings.core.instrumentation;
import com.android.settings.DialogCreatable;
import com.android.settings.core.lifecycle.ObservableDialogFragment; import com.android.settings.core.lifecycle.ObservableDialogFragment;
public abstract class InstrumentedDialogFragment extends ObservableDialogFragment public abstract class InstrumentedDialogFragment extends ObservableDialogFragment
implements Instrumentable { implements Instrumentable {
protected final DialogCreatable mDialogCreatable;
protected int mDialogId;
public InstrumentedDialogFragment() { public InstrumentedDialogFragment() {
this(null /* parentFragment */, 0 /* dialogId */);
}
/**
* Use this if the dialog is created via {@code DialogCreatable}
*/
public InstrumentedDialogFragment(DialogCreatable dialogCreatable, int dialogId) {
mDialogCreatable = dialogCreatable;
mDialogId = dialogId;
mLifecycle.addObserver(new VisibilityLoggerMixin(getMetricsCategory())); mLifecycle.addObserver(new VisibilityLoggerMixin(getMetricsCategory()));
} }

View File

@@ -155,6 +155,17 @@ public class NightDisplaySettings extends SettingsPreferenceFragment
return super.onCreateDialog(dialogId); return super.onCreateDialog(dialogId);
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) {
case DIALOG_START_TIME:
return MetricsEvent.DIALOG_NIGHT_DISPLAY_SET_START_TIME;
case DIALOG_END_TIME:
return MetricsEvent.DIALOG_NIGHT_DISPLAY_SET_END_TIME;
default:
return 0;
}
}
@Override @Override
public void onActivated(boolean activated) { public void onActivated(boolean activated) {
mActivatedPreference.setChecked(activated); mActivatedPreference.setChecked(activated);

View File

@@ -26,6 +26,7 @@ import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.android.internal.logging.MetricsProto;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
@@ -133,6 +134,18 @@ public class RestrictedProfileSettings extends AppRestrictionsFragment
return null; return null;
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) {
case DIALOG_ID_EDIT_USER_INFO:
return MetricsProto.MetricsEvent.DIALOG_USER_EDIT;
case DIALOG_CONFIRM_REMOVE:
return MetricsProto.MetricsEvent.DIALOG_USER_REMOVE;
default:
return 0;
}
}
private void removeUser() { private void removeUser() {
getView().post(new Runnable() { getView().post(new Runnable() {
public void run() { public void run() {

View File

@@ -26,6 +26,7 @@ import android.os.UserManager;
import android.support.v14.preference.SwitchPreference; import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import com.android.internal.logging.MetricsProto;
import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment; import com.android.settings.SettingsPreferenceFragment;
@@ -192,6 +193,20 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
throw new IllegalArgumentException("Unsupported dialogId " + dialogId); throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) {
case DIALOG_CONFIRM_REMOVE:
return MetricsProto.MetricsEvent.DIALOG_USER_REMOVE;
case DIALOG_CONFIRM_ENABLE_CALLING:
return MetricsProto.MetricsEvent.DIALOG_USER_ENABLE_CALLING;
case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
return MetricsProto.MetricsEvent.DIALOG_USER_ENABLE_CALLING_AND_SMS;
default:
return 0;
}
}
void removeUser() { void removeUser() {
mUserManager.removeUser(mUserInfo.id); mUserManager.removeUser(mUserInfo.id);
finishFragment(); finishFragment();

View File

@@ -622,6 +622,32 @@ public class UserSettings extends SettingsPreferenceFragment
} }
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) {
case DIALOG_CONFIRM_REMOVE:
return MetricsEvent.DIALOG_USER_REMOVE;
case DIALOG_USER_CANNOT_MANAGE:
return MetricsEvent.DIALOG_USER_CANNOT_MANAGE;
case DIALOG_ADD_USER:
return MetricsEvent.DIALOG_USER_ADD;
case DIALOG_SETUP_USER:
return MetricsEvent.DIALOG_USER_SETUP;
case DIALOG_SETUP_PROFILE:
return MetricsEvent.DIALOG_USER_SETUP_PROFILE;
case DIALOG_CHOOSE_USER_TYPE:
return MetricsEvent.DIALOG_USER_CHOOSE_TYPE;
case DIALOG_NEED_LOCKSCREEN:
return MetricsEvent.DIALOG_USER_NEED_LOCKSCREEN;
case DIALOG_CONFIRM_EXIT_GUEST:
return MetricsEvent.DIALOG_USER_CONFIRM_EXIT_GUEST;
case DIALOG_USER_PROFILE_EDITOR:
return MetricsEvent.DIALOG_USER_EDIT_PROFILE;
default:
return 0;
}
}
private static boolean emergencyInfoActivityPresent(Context context) { private static boolean emergencyInfoActivityPresent(Context context) {
Intent intent = new Intent(ACTION_EDIT_EMERGENCY_INFO).setPackage("com.android.emergency"); Intent intent = new Intent(ACTION_EDIT_EMERGENCY_INFO).setPackage("com.android.emergency");
List<ResolveInfo> infos = context.getPackageManager().queryIntentActivities(intent, 0); List<ResolveInfo> infos = context.getPackageManager().queryIntentActivities(intent, 0);

View File

@@ -25,6 +25,7 @@ import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
import android.util.Log; import android.util.Log;
import com.android.internal.logging.MetricsProto;
import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment; import com.android.settings.SettingsPreferenceFragment;
@@ -151,6 +152,16 @@ public class SavedAccessPointsWifiSettings extends SettingsPreferenceFragment
return super.onCreateDialog(dialogId); return super.onCreateDialog(dialogId);
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) {
case WifiSettings.WIFI_DIALOG_ID:
return MetricsProto.MetricsEvent.DIALOG_WIFI_SAVED_AP_EDIT;
default:
return 0;
}
}
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);

View File

@@ -597,6 +597,22 @@ public class WifiSettings extends RestrictedSettingsFragment
return super.onCreateDialog(dialogId); return super.onCreateDialog(dialogId);
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) {
case WIFI_DIALOG_ID:
return MetricsEvent.DIALOG_WIFI_AP_EDIT;
case WPS_PBC_DIALOG_ID:
return MetricsEvent.DIALOG_WIFI_PBC;
case WPS_PIN_DIALOG_ID:
return MetricsEvent.DIALOG_WIFI_PIN;
case WRITE_NFC_DIALOG_ID:
return MetricsEvent.DIALOG_WIFI_WRITE_NFC;
default:
return 0;
}
}
/** /**
* Shows the latest access points available with supplemental information like * Shows the latest access points available with supplemental information like
* the strength of network and the security for it. * the strength of network and the security for it.

View File

@@ -495,6 +495,21 @@ public class WifiP2pSettings extends SettingsPreferenceFragment
return MetricsEvent.WIFI_P2P; return MetricsEvent.WIFI_P2P;
} }
@Override
public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) {
case DIALOG_DISCONNECT:
return MetricsEvent.DIALOG_WIFI_P2P_DISCONNECT;
case DIALOG_CANCEL_CONNECT:
return MetricsEvent.DIALOG_WIFI_P2P_CANCEL_CONNECT;
case DIALOG_RENAME:
return MetricsEvent.DIALOG_WIFI_P2P_RENAME;
case DIALOG_DELETE_GROUP:
return MetricsEvent.DIALOG_WIFI_P2P_DELETE_GROUP;
}
return 0;
}
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
if (mSelectedWifiPeer != null) { if (mSelectedWifiPeer != null) {

View File

@@ -0,0 +1,88 @@
/*
* 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;
import android.app.Dialog;
import android.app.Fragment;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SettingsDialogFragmentTest {
private static final int DIALOG_ID = 15;
@Mock
private DialogCreatableFragment mDialogCreatable;
private SettingsPreferenceFragment.SettingsDialogFragment mDialogFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testGetMetrics_shouldGetMetricFromDialogCreatable() {
when(mDialogCreatable.getDialogMetricsCategory(DIALOG_ID)).thenReturn(1);
mDialogFragment =
new SettingsPreferenceFragment.SettingsDialogFragment(mDialogCreatable, DIALOG_ID);
mDialogFragment.getMetricsCategory();
// getDialogMetricsCategory called in constructor, and explicitly in test.
verify(mDialogCreatable, times(2)).getDialogMetricsCategory(DIALOG_ID);
}
@Test
public void testGetInvalidMetricsValue_shouldCrash() {
when(mDialogCreatable.getDialogMetricsCategory(DIALOG_ID)).thenReturn(-1);
try {
mDialogFragment = new SettingsPreferenceFragment.SettingsDialogFragment(
mDialogCreatable, DIALOG_ID);
} catch (IllegalStateException e) {
// getDialogMetricsCategory called in constructor
verify(mDialogCreatable).getDialogMetricsCategory(DIALOG_ID);
return;
}
fail("Should fail with IllegalStateException");
}
public static class DialogCreatableFragment extends Fragment implements DialogCreatable {
@Override
public Dialog onCreateDialog(int dialogId) {
return null;
}
@Override
public int getDialogMetricsCategory(int dialogId) {
return 0;
}
}
}

View File

@@ -1,3 +1,18 @@
/*
* 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; package com.android.settings;
import android.content.Context; import android.content.Context;