1 /*
2  * Copyright (C) 2022 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.batteryusage.db;
18 
19 import android.content.ContentValues;
20 
21 import androidx.room.Entity;
22 import androidx.room.PrimaryKey;
23 
24 import com.android.settings.fuelgauge.batteryusage.ConvertUtils;
25 
26 import com.google.errorprone.annotations.CanIgnoreReturnValue;
27 
28 import java.util.Locale;
29 
30 /** A {@link Entity} class to save app usage events into database. */
31 @Entity
32 public class AppUsageEventEntity {
33     /** Keys for accessing {@link ContentValues}. */
34     public static final String KEY_UID = "uid";
35 
36     public static final String KEY_USER_ID = "userId";
37     public static final String KEY_TIMESTAMP = "timestamp";
38     public static final String KEY_APP_USAGE_EVENT_TYPE = "appUsageEventType";
39     public static final String KEY_PACKAGE_NAME = "packageName";
40     public static final String KEY_INSTANCE_ID = "instanceId";
41     public static final String KEY_TASK_ROOT_PACKAGE_NAME = "taskRootPackageName";
42 
43     @PrimaryKey(autoGenerate = true)
44     private long mId;
45 
46     // Records the app relative information.
47     public final long uid;
48     public final long userId;
49     public final long timestamp;
50     public final int appUsageEventType;
51     public final String packageName;
52     public final int instanceId;
53     public final String taskRootPackageName;
54 
AppUsageEventEntity( final long uid, final long userId, final long timestamp, final int appUsageEventType, final String packageName, final int instanceId, final String taskRootPackageName)55     public AppUsageEventEntity(
56             final long uid,
57             final long userId,
58             final long timestamp,
59             final int appUsageEventType,
60             final String packageName,
61             final int instanceId,
62             final String taskRootPackageName) {
63         this.uid = uid;
64         this.userId = userId;
65         this.timestamp = timestamp;
66         this.appUsageEventType = appUsageEventType;
67         this.packageName = packageName;
68         this.instanceId = instanceId;
69         this.taskRootPackageName = taskRootPackageName;
70     }
71 
72     /** Sets the auto-generated content ID. */
setId(long id)73     public void setId(long id) {
74         this.mId = id;
75     }
76 
77     /** Gets the auto-generated content ID. */
getId()78     public long getId() {
79         return mId;
80     }
81 
82     @Override
toString()83     public String toString() {
84         final String recordAtDateTime = ConvertUtils.utcToLocalTimeForLogging(timestamp);
85         final StringBuilder builder =
86                 new StringBuilder()
87                         .append("\nAppUsageEvent{")
88                         .append(
89                                 String.format(
90                                         Locale.US,
91                                         "\n\tpackage=%s|uid=%d|userId=%d",
92                                         packageName,
93                                         uid,
94                                         userId))
95                         .append(
96                                 String.format(
97                                         Locale.US,
98                                         "\n\ttimestamp=%s|eventType=%d|instanceId=%d",
99                                         recordAtDateTime,
100                                         appUsageEventType,
101                                         instanceId))
102                         .append(
103                                 String.format(
104                                         Locale.US,
105                                         "\n\ttaskRootPackageName=%s",
106                                         taskRootPackageName));
107         return builder.toString();
108     }
109 
110     /** Creates new {@link AppUsageEventEntity} from {@link ContentValues}. */
create(ContentValues contentValues)111     public static AppUsageEventEntity create(ContentValues contentValues) {
112         Builder builder = AppUsageEventEntity.newBuilder();
113         if (contentValues.containsKey(KEY_UID)) {
114             builder.setUid(contentValues.getAsLong(KEY_UID));
115         }
116         if (contentValues.containsKey(KEY_USER_ID)) {
117             builder.setUserId(contentValues.getAsLong(KEY_USER_ID));
118         }
119         if (contentValues.containsKey(KEY_TIMESTAMP)) {
120             builder.setTimestamp(contentValues.getAsLong(KEY_TIMESTAMP));
121         }
122         if (contentValues.containsKey(KEY_APP_USAGE_EVENT_TYPE)) {
123             builder.setAppUsageEventType(contentValues.getAsInteger(KEY_APP_USAGE_EVENT_TYPE));
124         }
125         if (contentValues.containsKey(KEY_PACKAGE_NAME)) {
126             builder.setPackageName(contentValues.getAsString(KEY_PACKAGE_NAME));
127         }
128         if (contentValues.containsKey(KEY_INSTANCE_ID)) {
129             builder.setInstanceId(contentValues.getAsInteger(KEY_INSTANCE_ID));
130         }
131         if (contentValues.containsKey(KEY_TASK_ROOT_PACKAGE_NAME)) {
132             builder.setTaskRootPackageName(contentValues.getAsString(KEY_TASK_ROOT_PACKAGE_NAME));
133         }
134         return builder.build();
135     }
136 
137     /** Creates a new {@link Builder} instance. */
newBuilder()138     public static Builder newBuilder() {
139         return new Builder();
140     }
141 
142     /** A convenience builder class to improve readability. */
143     public static class Builder {
144         private long mUid;
145         private long mUserId;
146         private long mTimestamp;
147         private int mAppUsageEventType;
148         private String mPackageName;
149         private int mInstanceId;
150         private String mTaskRootPackageName;
151 
152         /** Sets the uid. */
153         @CanIgnoreReturnValue
setUid(final long uid)154         public Builder setUid(final long uid) {
155             this.mUid = uid;
156             return this;
157         }
158 
159         /** Sets the user ID. */
160         @CanIgnoreReturnValue
setUserId(final long userId)161         public Builder setUserId(final long userId) {
162             this.mUserId = userId;
163             return this;
164         }
165 
166         /** Sets the timestamp. */
167         @CanIgnoreReturnValue
setTimestamp(final long timestamp)168         public Builder setTimestamp(final long timestamp) {
169             this.mTimestamp = timestamp;
170             return this;
171         }
172 
173         /** Sets the app usage event type. */
174         @CanIgnoreReturnValue
setAppUsageEventType(final int appUsageEventType)175         public Builder setAppUsageEventType(final int appUsageEventType) {
176             this.mAppUsageEventType = appUsageEventType;
177             return this;
178         }
179 
180         /** Sets the package name. */
181         @CanIgnoreReturnValue
setPackageName(final String packageName)182         public Builder setPackageName(final String packageName) {
183             this.mPackageName = packageName;
184             return this;
185         }
186 
187         /** Sets the instance ID. */
188         @CanIgnoreReturnValue
setInstanceId(final int instanceId)189         public Builder setInstanceId(final int instanceId) {
190             this.mInstanceId = instanceId;
191             return this;
192         }
193 
194         /** Sets the task root package name. */
195         @CanIgnoreReturnValue
setTaskRootPackageName(final String taskRootPackageName)196         public Builder setTaskRootPackageName(final String taskRootPackageName) {
197             this.mTaskRootPackageName = taskRootPackageName;
198             return this;
199         }
200 
201         /** Builds the AppUsageEvent. */
build()202         public AppUsageEventEntity build() {
203             return new AppUsageEventEntity(
204                     mUid,
205                     mUserId,
206                     mTimestamp,
207                     mAppUsageEventType,
208                     mPackageName,
209                     mInstanceId,
210                     mTaskRootPackageName);
211         }
212 
Builder()213         private Builder() {}
214     }
215 }
216