Files
app_Settings/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
Matthew Fritze 3cd543fb85 Fix crash in non-indexable keys collection
Some of the AmbientDisplay preference controllers were
crashing when their isAvailable methods were being called
by their fragment's search index providers, which meant that
the entire collection of non-indexable keys failed. Thus,
all search results were showing up. In the case of a secondary
user, they were able to see developer options which crashed
settings when clicked.

There are two issues addressed in this cl.
1. Fix the crashes so the non-indexable keys collection works
2. Contain each fragment's collection, so that if a fragment does
crash, the damage is minimized.

Part 1 is checking that the config in isAvailable is not null,
and creating one if so.

Part 2 is fixed by surrounding the collection of non-indexable
keys in a try-catch, with an option in the catch to re-throw the
error if a system property is set. Thus, in a new pre-submit
instrumentation test, we can and docheck if any of the fragments crash
when collecting non-indexable keys.

Change-Id: I820bd9cb2649aa6faff7f82fcf575a62e41dc4fc
Fixes: 77486668
Test: atest NonIndexableCrashTest, robotests
2018-04-04 13:36:33 -07:00

103 lines
3.4 KiB
Java

/*
* 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.display;
import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import android.provider.Settings;
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settings.search.InlineSwitchPayload;
import com.android.settings.search.ResultPayload;
public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreferenceController {
private final int ON = 1;
private final int OFF = 0;
private static final int MY_USER = UserHandle.myUserId();
private AmbientDisplayConfiguration mConfig;
private OnPreferenceChangedCallback mCallback;
public interface OnPreferenceChangedCallback {
void onPreferenceChanged();
}
public AmbientDisplayAlwaysOnPreferenceController(Context context, String key) {
super(context, key);
}
@Override
public int getAvailabilityStatus() {
if (mConfig == null) {
mConfig = new AmbientDisplayConfiguration(mContext);
}
return isAvailable(mConfig) ? AVAILABLE : DISABLED_UNSUPPORTED;
}
@Override
public boolean isChecked() {
return mConfig.alwaysOnEnabled(MY_USER);
}
@Override
public boolean setChecked(boolean isChecked) {
int enabled = isChecked ? ON : OFF;
Settings.Secure.putInt(
mContext.getContentResolver(), Settings.Secure.DOZE_ALWAYS_ON, enabled);
if (mCallback != null) {
mCallback.onPreferenceChanged();
}
return true;
}
public void setConfig(AmbientDisplayConfiguration config) {
mConfig = config;
}
public void setCallback(OnPreferenceChangedCallback callback) {
mCallback = callback;
}
public static boolean isAlwaysOnEnabled(AmbientDisplayConfiguration config) {
return config.alwaysOnEnabled(MY_USER);
}
public static boolean isAvailable(AmbientDisplayConfiguration config) {
return config.alwaysOnAvailableForUser(MY_USER);
}
public static boolean accessibilityInversionEnabled(AmbientDisplayConfiguration config) {
return config.accessibilityInversionEnabled(MY_USER);
}
@Override
public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
AmbientDisplaySettings.class.getName(), getPreferenceKey(),
mContext.getString(R.string.ambient_display_screen_title));
return new InlineSwitchPayload(Settings.Secure.DOZE_ALWAYS_ON,
ResultPayload.SettingsSource.SECURE, ON /* onValue */, intent, isAvailable(),
ON /* defaultValue */);
}
}