Merge changes I77a53f70,I853d3611
* changes: Add functions for table action. Create table to store user action.
This commit is contained in:
@@ -38,11 +38,14 @@ import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
|
||||
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
|
||||
import com.android.settings.fuelgauge.batterytip.StatsManagerConfig;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
import com.android.settingslib.utils.PowerUtil;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -101,8 +104,8 @@ public class BatteryUtils {
|
||||
mContext = context;
|
||||
mPackageManager = context.getPackageManager();
|
||||
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
|
||||
mPowerUsageFeatureProvider = FeatureFactory.getFactory(
|
||||
context).getPowerUsageFeatureProvider(context);
|
||||
mPowerUsageFeatureProvider = FeatureFactory.getFactory(context)
|
||||
.getPowerUsageFeatureProvider(context);
|
||||
}
|
||||
|
||||
public long getProcessTimeMs(@StatusType int type, @Nullable BatteryStats.Uid uid,
|
||||
@@ -400,6 +403,18 @@ public class BatteryUtils {
|
||||
}
|
||||
// Control whether app could run jobs in the background
|
||||
mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mode);
|
||||
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
final BatteryDatabaseManager batteryDatabaseManager = BatteryDatabaseManager
|
||||
.getInstance(mContext);
|
||||
if (mode == AppOpsManager.MODE_IGNORED) {
|
||||
batteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
|
||||
uid, packageName, System.currentTimeMillis());
|
||||
} else if (mode == AppOpsManager.MODE_ALLOWED) {
|
||||
batteryDatabaseManager.deleteAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
|
||||
uid, packageName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isForceAppStandbyEnabled(int uid, String packageName) {
|
||||
|
@@ -22,6 +22,8 @@ import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
import android.util.SparseLongArray;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
@@ -29,7 +31,9 @@ import com.android.settings.Utils;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipDialogFragment;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
@@ -37,6 +41,7 @@ import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
import com.android.settings.widget.AppCheckBoxPreference;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.utils.StringUtil;
|
||||
import com.android.settingslib.widget.FooterPreferenceMixinCompat;
|
||||
|
||||
import java.util.List;
|
||||
@@ -57,6 +62,7 @@ public class RestrictedAppDetails extends DashboardFragment implements
|
||||
@VisibleForTesting
|
||||
static final String EXTRA_APP_INFO_LIST = "app_info_list";
|
||||
private static final String KEY_PREF_RESTRICTED_APP_LIST = "restrict_app_list";
|
||||
private static final long TIME_NULL = -1;
|
||||
|
||||
@VisibleForTesting
|
||||
List<AppInfo> mAppInfos;
|
||||
@@ -68,6 +74,8 @@ public class RestrictedAppDetails extends DashboardFragment implements
|
||||
BatteryUtils mBatteryUtils;
|
||||
@VisibleForTesting
|
||||
PackageManager mPackageManager;
|
||||
@VisibleForTesting
|
||||
BatteryDatabaseManager mBatteryDatabaseManager;
|
||||
private final FooterPreferenceMixinCompat mFooterPreferenceMixin =
|
||||
new FooterPreferenceMixinCompat(this, getSettingsLifecycle());
|
||||
|
||||
@@ -96,6 +104,7 @@ public class RestrictedAppDetails extends DashboardFragment implements
|
||||
mPackageManager = context.getPackageManager();
|
||||
mIconDrawableFactory = IconDrawableFactory.newInstance(context);
|
||||
mBatteryUtils = BatteryUtils.getInstance(context);
|
||||
mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(context);
|
||||
|
||||
refreshUi();
|
||||
}
|
||||
@@ -135,6 +144,9 @@ public class RestrictedAppDetails extends DashboardFragment implements
|
||||
void refreshUi() {
|
||||
mRestrictedAppListGroup.removeAll();
|
||||
final Context context = getPrefContext();
|
||||
final SparseLongArray timestampArray = mBatteryDatabaseManager
|
||||
.queryActionTime(AnomalyDatabaseHelper.ActionType.RESTRICTION);
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
for (int i = 0, size = mAppInfos.size(); i < size; i++) {
|
||||
final CheckBoxPreference checkBoxPreference = new AppCheckBoxPreference(context);
|
||||
@@ -158,9 +170,16 @@ public class RestrictedAppDetails extends DashboardFragment implements
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
final long timestamp = timestampArray.get(appInfo.uid, TIME_NULL);
|
||||
if (timestamp != TIME_NULL) {
|
||||
checkBoxPreference.setSummary(getString(R.string.restricted_app_time_summary,
|
||||
StringUtil.formatRelativeTime(context, now - timestamp, false)));
|
||||
}
|
||||
final CharSequence test = checkBoxPreference.getSummaryOn();
|
||||
mRestrictedAppListGroup.addPreference(checkBoxPreference);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "Can't find package: " + appInfo.packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ public class AnomalyDatabaseHelper extends SQLiteOpenHelper {
|
||||
private static final String TAG = "BatteryDatabaseHelper";
|
||||
|
||||
private static final String DATABASE_NAME = "battery_settings.db";
|
||||
private static final int DATABASE_VERSION = 4;
|
||||
private static final int DATABASE_VERSION = 5;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({State.NEW,
|
||||
@@ -45,8 +45,15 @@ public class AnomalyDatabaseHelper extends SQLiteOpenHelper {
|
||||
int AUTO_HANDLED = 2;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({ActionType.RESTRICTION})
|
||||
public @interface ActionType {
|
||||
int RESTRICTION = 0;
|
||||
}
|
||||
|
||||
public interface Tables {
|
||||
String TABLE_ANOMALY = "anomaly";
|
||||
String TABLE_ACTION = "action";
|
||||
}
|
||||
|
||||
public interface AnomalyColumns {
|
||||
@@ -91,6 +98,42 @@ public class AnomalyDatabaseHelper extends SQLiteOpenHelper {
|
||||
+ AnomalyColumns.ANOMALY_STATE + "," + AnomalyColumns.TIME_STAMP_MS + ")"
|
||||
+ ")";
|
||||
|
||||
|
||||
public interface ActionColumns {
|
||||
/**
|
||||
* The package name of an app been performed an action
|
||||
*/
|
||||
String PACKAGE_NAME = "package_name";
|
||||
/**
|
||||
* The uid of an app been performed an action
|
||||
*/
|
||||
String UID = "uid";
|
||||
/**
|
||||
* The type of user action
|
||||
* @see ActionType
|
||||
*/
|
||||
String ACTION_TYPE = "action_type";
|
||||
/**
|
||||
* The time when action been performed
|
||||
*/
|
||||
String TIME_STAMP_MS = "time_stamp_ms";
|
||||
}
|
||||
|
||||
private static final String CREATE_ACTION_TABLE =
|
||||
"CREATE TABLE " + Tables.TABLE_ACTION +
|
||||
"(" +
|
||||
ActionColumns.UID +
|
||||
" INTEGER NOT NULL, " +
|
||||
ActionColumns.PACKAGE_NAME +
|
||||
" TEXT, " +
|
||||
ActionColumns.ACTION_TYPE +
|
||||
" INTEGER NOT NULL, " +
|
||||
ActionColumns.TIME_STAMP_MS +
|
||||
" INTEGER NOT NULL, " +
|
||||
" PRIMARY KEY (" + ActionColumns.ACTION_TYPE + "," + ActionColumns.UID + ","
|
||||
+ ActionColumns.PACKAGE_NAME + ")"
|
||||
+ ")";
|
||||
|
||||
private static AnomalyDatabaseHelper sSingleton;
|
||||
|
||||
public static synchronized AnomalyDatabaseHelper getInstance(Context context) {
|
||||
@@ -109,11 +152,6 @@ public class AnomalyDatabaseHelper extends SQLiteOpenHelper {
|
||||
bootstrapDB(db);
|
||||
}
|
||||
|
||||
private void bootstrapDB(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_ANOMALY_TABLE);
|
||||
Log.i(TAG, "Bootstrapped database");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion < DATABASE_VERSION) {
|
||||
@@ -137,7 +175,14 @@ public class AnomalyDatabaseHelper extends SQLiteOpenHelper {
|
||||
bootstrapDB(db);
|
||||
}
|
||||
|
||||
private void bootstrapDB(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_ANOMALY_TABLE);
|
||||
db.execSQL(CREATE_ACTION_TABLE);
|
||||
Log.i(TAG, "Bootstrapped database");
|
||||
}
|
||||
|
||||
private void dropTables(SQLiteDatabase db) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + Tables.TABLE_ANOMALY);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + Tables.TABLE_ACTION);
|
||||
}
|
||||
}
|
||||
|
@@ -17,6 +17,8 @@
|
||||
package com.android.settings.fuelgauge.batterytip;
|
||||
|
||||
import static android.database.sqlite.SQLiteDatabase.CONFLICT_IGNORE;
|
||||
import static android.database.sqlite.SQLiteDatabase.CONFLICT_REPLACE;
|
||||
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||
.ANOMALY_STATE;
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||
@@ -26,6 +28,7 @@ import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.An
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||
.TIME_STAMP_MS;
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns.UID;
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.Tables.TABLE_ACTION;
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.Tables.TABLE_ANOMALY;
|
||||
|
||||
import android.content.ContentValues;
|
||||
@@ -34,12 +37,15 @@ import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.SparseLongArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.ActionColumns;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
/**
|
||||
@@ -158,4 +164,65 @@ public class BatteryDatabaseManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query latest timestamps when an app has been performed action {@code type}
|
||||
*
|
||||
* @param type of action been performed
|
||||
* @return {@link SparseLongArray} where key is uid and value is timestamp
|
||||
*/
|
||||
public synchronized SparseLongArray queryActionTime(
|
||||
@AnomalyDatabaseHelper.ActionType int type) {
|
||||
final SparseLongArray timeStamps = new SparseLongArray();
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getReadableDatabase()) {
|
||||
final String[] projection = {ActionColumns.UID, ActionColumns.TIME_STAMP_MS};
|
||||
final String selection = ActionColumns.ACTION_TYPE + " = ? ";
|
||||
final String[] selectionArgs = new String[]{String.valueOf(type)};
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_ACTION, projection, selection, selectionArgs,
|
||||
null /* groupBy */, null /* having */, null /* orderBy */)) {
|
||||
final int uidIndex = cursor.getColumnIndex(ActionColumns.UID);
|
||||
final int timestampIndex = cursor.getColumnIndex(ActionColumns.TIME_STAMP_MS);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
final int uid = cursor.getInt(uidIndex);
|
||||
final long timeStamp = cursor.getLong(timestampIndex);
|
||||
timeStamps.append(uid, timeStamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return timeStamps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an action, or update it if already existed
|
||||
*/
|
||||
public synchronized boolean insertAction(@AnomalyDatabaseHelper.ActionType int type,
|
||||
int uid, String packageName, long timestampMs) {
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(ActionColumns.UID, uid);
|
||||
values.put(ActionColumns.PACKAGE_NAME, packageName);
|
||||
values.put(ActionColumns.ACTION_TYPE, type);
|
||||
values.put(ActionColumns.TIME_STAMP_MS, timestampMs);
|
||||
return db.insertWithOnConflict(TABLE_ACTION, null, values, CONFLICT_REPLACE) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an action
|
||||
*/
|
||||
public synchronized boolean deleteAction(@AnomalyDatabaseHelper.ActionType int type,
|
||||
int uid, String packageName) {
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
|
||||
final String where =
|
||||
ActionColumns.ACTION_TYPE + " = ? AND " + ActionColumns.UID + " = ? AND "
|
||||
+ ActionColumns.PACKAGE_NAME + " = ? ";
|
||||
final String[] whereArgs = new String[]{String.valueOf(type), String.valueOf(uid),
|
||||
String.valueOf(packageName)};
|
||||
|
||||
return db.delete(TABLE_ACTION, where, whereArgs) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user