Framework for the anomaly detection.

This cl adds the following components for anomaly dection:
1. AnomalyLoader: run all the anomaly checks in the background
2. Anomaly: Data class to represent what anomaly it is
3. Detector: Different kinds of anomaly detector with common interface
4. Action:  Suggestions when facing anomaly(Force stop, uninstall)
5. AnomalyDialogFragment: show the confirm dialog for action
6. AnomalyPreferenceController: handle update and click for
anomalyPreference, since it will be used in multiple fragments.
7. AnomalyUtils: utility class for anomaly

This cl also adds skeleton for the wakelock check and action. Following
cls will add real implementation about it.

Bug: 36924669
Test: RunSettingsRoboTests
Change-Id: I89fc4b6963757869b93791b4275ca53c04ab9604
This commit is contained in:
jackqdyulei
2017-04-25 11:30:06 -07:00
parent 4869effb72
commit df6dd14799
15 changed files with 875 additions and 1 deletions

View File

@@ -0,0 +1,103 @@
/*
* 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.fuelgauge.anomaly;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
/**
* Dialog Fragment to show action dialog for each anomaly
*/
public class AnomalyDialogFragment extends InstrumentedDialogFragment implements
DialogInterface.OnClickListener {
private static final String ARG_ANOMALY = "anomaly";
@VisibleForTesting
Anomaly mAnomaly;
/**
* Listener to give the control back to target fragment
*/
public interface AnomalyDialogListener {
/**
* This method is invoked once anomaly is handled, then target fragment could do
* extra work. One example is that fragment could remove the anomaly preference
* since it has been handled
*
* @param anomaly that has been handled
*/
void onAnomalyHandled(Anomaly anomaly);
}
public static AnomalyDialogFragment newInstance(Anomaly anomaly) {
AnomalyDialogFragment dialogFragment = new AnomalyDialogFragment();
Bundle args = new Bundle(1);
args.putParcelable(ARG_ANOMALY, anomaly);
dialogFragment.setArguments(args);
return dialogFragment;
}
@Override
public int getMetricsCategory() {
// TODO(b/37681923): add anomaly metric id
return 0;
}
@Override
public void onClick(DialogInterface dialog, int which) {
final AnomalyDialogListener lsn = (AnomalyDialogListener) getTargetFragment();
if (lsn == null) {
return;
}
final AnomalyAction anomalyAction = AnomalyUtils.getAnomalyAction(mAnomaly.type);
anomalyAction.handlePositiveAction(mAnomaly.packageName);
lsn.onAnomalyHandled(mAnomaly);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle bundle = getArguments();
mAnomaly = bundle.getParcelable(ARG_ANOMALY);
final Context context = getContext();
final AnomalyAction anomalyAction = AnomalyUtils.getAnomalyAction(mAnomaly.type);
switch (anomalyAction.getActionType()) {
case Anomaly.AnomalyActionType.FORCE_STOP:
return new AlertDialog.Builder(context)
.setTitle(R.string.force_stop_dlg_title)
.setMessage(R.string.force_stop_dlg_text)
.setPositiveButton(R.string.dlg_ok, this)
.setNegativeButton(R.string.dlg_cancel, null)
.create();
default:
throw new IllegalArgumentException("unknown type " + mAnomaly.type);
}
}
}