• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.fuelgauge.batterytip;
18 
19 import android.content.Context;
20 import android.database.sqlite.SQLiteDatabase;
21 import android.database.sqlite.SQLiteOpenHelper;
22 import android.util.Log;
23 
24 import androidx.annotation.IntDef;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 
29 /**
30  * Database controls the anomaly logging(e.g. packageName, anomalyType and time)
31  */
32 public class AnomalyDatabaseHelper extends SQLiteOpenHelper {
33     private static final String TAG = "BatteryDatabaseHelper";
34 
35     private static final String DATABASE_NAME = "battery_settings.db";
36     private static final int DATABASE_VERSION = 5;
37 
38     @Retention(RetentionPolicy.SOURCE)
39     @IntDef({State.NEW,
40             State.HANDLED,
41             State.AUTO_HANDLED})
42     public @interface State {
43         int NEW = 0;
44         int HANDLED = 1;
45         int AUTO_HANDLED = 2;
46     }
47 
48     @Retention(RetentionPolicy.SOURCE)
49     @IntDef({ActionType.RESTRICTION})
50     public @interface ActionType {
51         int RESTRICTION = 0;
52     }
53 
54     public interface Tables {
55         String TABLE_ANOMALY = "anomaly";
56         String TABLE_ACTION = "action";
57     }
58 
59     public interface AnomalyColumns {
60         /**
61          * The package name of the anomaly app
62          */
63         String PACKAGE_NAME = "package_name";
64         /**
65          * The uid of the anomaly app
66          */
67         String UID = "uid";
68         /**
69          * The type of the anomaly app
70          * @see StatsManagerConfig.AnomalyType
71          */
72         String ANOMALY_TYPE = "anomaly_type";
73         /**
74          * The state of the anomaly app
75          * @see State
76          */
77         String ANOMALY_STATE = "anomaly_state";
78         /**
79          * The time when anomaly happens
80          */
81         String TIME_STAMP_MS = "time_stamp_ms";
82     }
83 
84     private static final String CREATE_ANOMALY_TABLE =
85             "CREATE TABLE " + Tables.TABLE_ANOMALY +
86                     "(" +
87                     AnomalyColumns.UID +
88                     " INTEGER NOT NULL, " +
89                     AnomalyColumns.PACKAGE_NAME +
90                     " TEXT, " +
91                     AnomalyColumns.ANOMALY_TYPE +
92                     " INTEGER NOT NULL, " +
93                     AnomalyColumns.ANOMALY_STATE +
94                     " INTEGER NOT NULL, " +
95                     AnomalyColumns.TIME_STAMP_MS +
96                     " INTEGER NOT NULL, " +
97                     " PRIMARY KEY (" + AnomalyColumns.UID + "," + AnomalyColumns.ANOMALY_TYPE + ","
98                     + AnomalyColumns.ANOMALY_STATE + "," + AnomalyColumns.TIME_STAMP_MS + ")"
99                     + ")";
100 
101 
102     public interface ActionColumns {
103         /**
104          * The package name of an app been performed an action
105          */
106         String PACKAGE_NAME = "package_name";
107         /**
108          * The uid of an app been performed an action
109          */
110         String UID = "uid";
111         /**
112          * The type of user action
113          * @see ActionType
114          */
115         String ACTION_TYPE = "action_type";
116         /**
117          * The time when action been performed
118          */
119         String TIME_STAMP_MS = "time_stamp_ms";
120     }
121 
122     private static final String CREATE_ACTION_TABLE =
123             "CREATE TABLE " + Tables.TABLE_ACTION +
124                     "(" +
125                     ActionColumns.UID +
126                     " INTEGER NOT NULL, " +
127                     ActionColumns.PACKAGE_NAME +
128                     " TEXT, " +
129                     ActionColumns.ACTION_TYPE +
130                     " INTEGER NOT NULL, " +
131                     ActionColumns.TIME_STAMP_MS +
132                     " INTEGER NOT NULL, " +
133                     " PRIMARY KEY (" + ActionColumns.ACTION_TYPE + "," + ActionColumns.UID + ","
134                     + ActionColumns.PACKAGE_NAME + ")"
135                     + ")";
136 
137     private static AnomalyDatabaseHelper sSingleton;
138 
getInstance(Context context)139     public static synchronized AnomalyDatabaseHelper getInstance(Context context) {
140         if (sSingleton == null) {
141             sSingleton = new AnomalyDatabaseHelper(context.getApplicationContext());
142         }
143         return sSingleton;
144     }
145 
AnomalyDatabaseHelper(Context context)146     private AnomalyDatabaseHelper(Context context) {
147         super(context, DATABASE_NAME, null, DATABASE_VERSION);
148     }
149 
150     @Override
onCreate(SQLiteDatabase db)151     public void onCreate(SQLiteDatabase db) {
152         bootstrapDB(db);
153     }
154 
155     @Override
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)156     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
157         if (oldVersion < DATABASE_VERSION) {
158             Log.w(TAG, "Detected schema version '" + oldVersion + "'. " +
159                     "Index needs to be rebuilt for schema version '" + newVersion + "'.");
160             // We need to drop the tables and recreate them
161             reconstruct(db);
162         }
163     }
164 
165     @Override
onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)166     public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
167         Log.w(TAG, "Detected schema version '" + oldVersion + "'. " +
168                 "Index needs to be rebuilt for schema version '" + newVersion + "'.");
169         // We need to drop the tables and recreate them
170         reconstruct(db);
171     }
172 
reconstruct(SQLiteDatabase db)173     public void reconstruct(SQLiteDatabase db) {
174         dropTables(db);
175         bootstrapDB(db);
176     }
177 
bootstrapDB(SQLiteDatabase db)178     private void bootstrapDB(SQLiteDatabase db) {
179         db.execSQL(CREATE_ANOMALY_TABLE);
180         db.execSQL(CREATE_ACTION_TABLE);
181         Log.i(TAG, "Bootstrapped database");
182     }
183 
dropTables(SQLiteDatabase db)184     private void dropTables(SQLiteDatabase db) {
185         db.execSQL("DROP TABLE IF EXISTS " + Tables.TABLE_ANOMALY);
186         db.execSQL("DROP TABLE IF EXISTS " + Tables.TABLE_ACTION);
187     }
188 }
189