import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.ConfirmationDialogController;
import com.android.settingslib.development.AbstractEnableAdbPreferenceController;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
import com.android.settingslib.development.SystemPropPoker;
private static final int[] MOCK_LOCATION_APP_OPS = new int[]{AppOpsManager.OP_MOCK_LOCATION};
+ private static final String STATE_SHOWING_DIALOG_KEY = "showing_dialog_key";
+
+ private String mPendingDialogKey;
+
private IWindowManager mWindowManager;
private IBackupManager mBackupManager;
private IWebViewUpdateService mWebViewUpdateService;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ if (icicle != null) {
+ // Don't show this in onCreate since we might be on the back stack
+ mPendingDialogKey = icicle.getString(STATE_SHOWING_DIALOG_KEY);
+ }
+
mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
mBackupManager = IBackupManager.Stub.asInterface(
ServiceManager.getService(Context.BACKUP_SERVICE));
mColorModePreference.startListening();
mColorModePreference.updateCurrentAndSupported();
}
+
+ if (mPendingDialogKey != null) {
+ recreateDialogForKey(mPendingDialogKey);
+ mPendingDialogKey = null;
+ }
}
@Override
}
@Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString(STATE_SHOWING_DIALOG_KEY, getKeyForShowingDialog());
+ }
+
+ @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
IntentFilter filter = new IntentFilter();
return false;
}
+ /**
+ * Iterates through preference controllers that show confirmation dialogs and returns the
+ * preference key for the first currently showing dialog. Ideally there should only ever be one.
+ * @return Preference key, or null if no dialog is showing
+ */
+ private String getKeyForShowingDialog() {
+ // TODO: iterate through a fragment-wide list of PreferenceControllers and just pick out the
+ // ConfirmationDialogController objects
+ final List<ConfirmationDialogController> dialogControllers = new ArrayList<>(2);
+ dialogControllers.add(mEnableAdbController);
+ dialogControllers.add(mLogpersistController);
+ for (ConfirmationDialogController dialogController : dialogControllers) {
+ if (dialogController.isConfirmationDialogShowing()) {
+ return dialogController.getPreferenceKey();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Re-show the dialog we lost previously
+ * @param preferenceKey Key for the preference the dialog is for
+ */
+ private void recreateDialogForKey(String preferenceKey) {
+ // TODO: iterate through a fragment-wide list of PreferenceControllers and just pick out the
+ // ConfirmationDialogController objects
+ final List<ConfirmationDialogController> dialogControllers = new ArrayList<>(2);
+ dialogControllers.add(mEnableAdbController);
+ dialogControllers.add(mLogpersistController);
+ for (ConfirmationDialogController dialogController : dialogControllers) {
+ if (TextUtils.equals(preferenceKey, dialogController.getPreferenceKey())) {
+ dialogController.showConfirmationDialog(findPreference(preferenceKey));
+ }
+ }
+ }
+
private void dismissDialogs() {
- mEnableAdbController.dismissDialogs();
+ mEnableAdbController.dismissConfirmationDialog();
if (mAdbKeysDialog != null) {
mAdbKeysDialog.dismiss();
mAdbKeysDialog = null;
mEnableDialog.dismiss();
mEnableDialog = null;
}
- mLogpersistController.dismissDialogs();
+ mLogpersistController.dismissConfirmationDialog();
}
public void onClick(DialogInterface dialog, int which) {
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
-import android.provider.Settings;
-import android.support.v14.preference.SwitchPreference;
+import android.support.annotation.Nullable;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.TwoStatePreference;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
}
@Override
- public void showConfirmationDialog(SwitchPreference preference) {
+ public void showConfirmationDialog(@Nullable Preference preference) {
+ if (preference == null) {
+ return;
+ }
+ final TwoStatePreference twoStatePreference = (TwoStatePreference) preference;
mDialogClicked = false;
- dismissDialogs();
+ dismissConfirmationDialog();
mAdbDialog = new AlertDialog.Builder(mContext).setMessage(
mContext.getString(R.string.adb_warning_message))
.setTitle(R.string.adb_warning_title)
.setPositiveButton(android.R.string.yes, (dialog, which) -> {
mDialogClicked = true;
writeAdbSetting(true);
+ twoStatePreference.setChecked(true);
})
- .setNegativeButton(android.R.string.no, (dialog, which) -> {
- preference.setChecked(false);
- })
+ .setNegativeButton(android.R.string.no,
+ (dialog, which) -> twoStatePreference.setChecked(false))
.show();
mAdbDialog.setOnDismissListener(dialog -> {
// Assuming that onClick gets called first
if (!mDialogClicked) {
- preference.setChecked(false);
+ twoStatePreference.setChecked(false);
}
mAdbDialog = null;
});
}
- public void dismissDialogs() {
+ @Override
+ public void dismissConfirmationDialog() {
if (mAdbDialog != null) {
mAdbDialog.dismiss();
mAdbDialog = null;
}
}
+
+ @Override
+ public boolean isConfirmationDialogShowing() {
+ return mAdbDialog != null;
+ }
}
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
-import android.support.v7.preference.ListPreference;
+import android.support.annotation.Nullable;
+import android.support.v7.preference.Preference;
+import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.development.AbstractLogpersistPreferenceController;
}
@Override
- public void showConfirmationDialog(ListPreference preference) {
- if (mLogpersistClearDialog != null) dismissDialogs();
- mLogpersistClearDialog = new AlertDialog.Builder(mContext).setMessage(
- mContext.getString(
- com.android.settingslib.R.string.dev_logpersist_clear_warning_message))
- .setTitle(com.android.settingslib.R.string.dev_logpersist_clear_warning_title)
+ public void showConfirmationDialog(@Nullable Preference preference) {
+ if (preference == null) {
+ return;
+ }
+ if (mLogpersistClearDialog != null) dismissConfirmationDialog();
+ mLogpersistClearDialog = new AlertDialog.Builder(mContext)
+ .setMessage(R.string.dev_logpersist_clear_warning_message)
+ .setTitle(R.string.dev_logpersist_clear_warning_title)
.setPositiveButton(android.R.string.yes, (dialog, which) -> setLogpersistOff(true))
.setNegativeButton(android.R.string.no, (dialog, which) -> updateLogpersistValues())
.show();
mLogpersistClearDialog.setOnDismissListener(dialog -> mLogpersistClearDialog = null);
-
}
- public void dismissDialogs() {
+ @Override
+ public void dismissConfirmationDialog() {
if (mLogpersistClearDialog != null) {
mLogpersistClearDialog.dismiss();
mLogpersistClearDialog = null;
}
}
+
+ @Override
+ public boolean isConfirmationDialogShowing() {
+ return mLogpersistClearDialog != null;
+ }
}
--- /dev/null
+/*
+ * 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.google.common.truth.Truth.assertThat;
+
+import android.support.v14.preference.SwitchPreference;
+
+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.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class EnableAdbPreferenceControllerTest {
+
+ @Mock
+ private SwitchPreference mSwitchPreference;
+
+ private EnableAdbPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mController
+ = new EnableAdbPreferenceController(RuntimeEnvironment.application);
+ }
+
+ @Test
+ public void testIsConfirmationDialogShowing() {
+ assertThat(mController.isConfirmationDialogShowing()).isFalse();
+ mController.showConfirmationDialog(mSwitchPreference);
+ assertThat(mController.isConfirmationDialogShowing()).isTrue();
+ mController.dismissConfirmationDialog();
+ assertThat(mController.isConfirmationDialogShowing()).isFalse();
+ }
+}
--- /dev/null
+/*
+ * 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.google.common.truth.Truth.assertThat;
+
+import android.support.v7.preference.ListPreference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+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)
+public class LogpersistPreferenceControllerTest {
+
+ private Lifecycle mLifecycle = new Lifecycle();
+
+ @Mock
+ private ListPreference mListPreference;
+
+ private LogpersistPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mController
+ = new LogpersistPreferenceController(RuntimeEnvironment.application, mLifecycle);
+ }
+
+ @Test
+ public void testIsConfirmationDialogShowing() {
+ assertThat(mController.isConfirmationDialogShowing()).isFalse();
+ mController.showConfirmationDialog(mListPreference);
+ assertThat(mController.isConfirmationDialogShowing()).isTrue();
+ mController.dismissConfirmationDialog();
+ assertThat(mController.isConfirmationDialogShowing()).isFalse();
+ }
+}