1 /*
2  * Copyright (C) 2023 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 android.app;
18 
19 import android.annotation.IntDef;
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SystemApi;
24 
25 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy;
27 
28 /**
29  * Represents a query that contains information required for StatsManager to return relevant metric
30  * data.
31  *
32  * @hide
33  */
34 @SystemApi
35 public final class StatsQuery {
36     /**
37      * Default value for SQL dialect.
38      */
39     public static final int DIALECT_UNKNOWN = 0;
40 
41     /**
42      * Query passed is of SQLite dialect.
43      */
44     public static final int DIALECT_SQLITE = 1;
45 
46     /**
47      * @hide
48      */
49     @IntDef(prefix = {"DIALECT_"}, value = {DIALECT_UNKNOWN, DIALECT_SQLITE})
50     @Retention(RetentionPolicy.SOURCE)
51     @interface SqlDialect {
52     }
53 
54     private final int sqlDialect;
55     private final String rawSql;
56     private final int minClientSqlVersion;
57     private final byte[] policyConfig;
StatsQuery(int sqlDialect, @NonNull String rawSql, int minClientSqlVersion, @Nullable byte[] policyConfig)58     private StatsQuery(int sqlDialect, @NonNull String rawSql, int minClientSqlVersion,
59             @Nullable byte[] policyConfig) {
60         this.sqlDialect = sqlDialect;
61         this.rawSql = rawSql;
62         this.minClientSqlVersion = minClientSqlVersion;
63         this.policyConfig = policyConfig;
64     }
65 
66     /**
67      * Returns the SQL dialect of the query.
68      */
getSqlDialect()69     public @SqlDialect int getSqlDialect() {
70         return sqlDialect;
71     }
72 
73     /**
74      * Returns the raw SQL of the query.
75      */
76     @NonNull
getRawSql()77     public String getRawSql() {
78         return rawSql;
79     }
80 
81     /**
82      * Returns the minimum SQL client library version required to execute the query.
83      */
84     @IntRange(from = 0)
getMinSqlClientVersion()85     public int getMinSqlClientVersion() {
86         return minClientSqlVersion;
87     }
88 
89     /**
90      * Returns the wire-encoded StatsPolicyConfig proto that contains information to verify the
91      * query against a policy defined on the underlying data. Returns null if no policy was set.
92      */
93     @Nullable
getPolicyConfig()94     public byte[] getPolicyConfig() {
95         return policyConfig;
96     }
97 
98     /**
99      * Builder for constructing a StatsQuery object.
100      * <p>Usage:</p>
101      * <code>
102      * StatsQuery statsQuery = new StatsQuery.Builder("SELECT * from table")
103      * .setSqlDialect(StatsQuery.DIALECT_SQLITE)
104      * .setMinClientSqlVersion(1)
105      * .build();
106      * </code>
107      */
108     public static final class Builder {
109         private int sqlDialect;
110         private String rawSql;
111         private int minSqlClientVersion;
112         private byte[] policyConfig;
113 
114         /**
115          * Returns a new StatsQuery.Builder object for constructing StatsQuery for
116          * StatsManager#query
117          */
Builder(@onNull final String rawSql)118         public Builder(@NonNull final String rawSql) {
119             if (rawSql == null) {
120                 throw new IllegalArgumentException("rawSql must not be null");
121             }
122             this.rawSql = rawSql;
123             this.sqlDialect = DIALECT_SQLITE;
124             this.minSqlClientVersion = 1;
125             this.policyConfig = null;
126         }
127 
128         /**
129          * Sets the SQL dialect of the query.
130          *
131          * @param sqlDialect The SQL dialect of the query.
132          */
133         @NonNull
setSqlDialect(@qlDialect final int sqlDialect)134         public Builder setSqlDialect(@SqlDialect final int sqlDialect) {
135             this.sqlDialect = sqlDialect;
136             return this;
137         }
138 
139         /**
140          * Sets the minimum SQL client library version required to execute the query.
141          *
142          * @param minSqlClientVersion The minimum SQL client version required to execute the query.
143          */
144         @NonNull
setMinSqlClientVersion(@ntRangefrom = 0) final int minSqlClientVersion)145         public Builder setMinSqlClientVersion(@IntRange(from = 0) final int minSqlClientVersion) {
146             if (minSqlClientVersion < 0) {
147                 throw new IllegalArgumentException("minSqlClientVersion must be a "
148                         + "positive integer");
149             }
150             this.minSqlClientVersion = minSqlClientVersion;
151             return this;
152         }
153 
154         /**
155          * Sets the wire-encoded StatsPolicyConfig proto that contains information to verify the
156          * query against a policy defined on the underlying data.
157          *
158          * @param policyConfig The wire-encoded StatsPolicyConfig proto.
159          */
160         @NonNull
setPolicyConfig(@onNull final byte[] policyConfig)161         public Builder setPolicyConfig(@NonNull final byte[] policyConfig) {
162             this.policyConfig = policyConfig;
163             return this;
164         }
165 
166         /**
167          * Builds a new instance of {@link StatsQuery}.
168          *
169          * @return A new instance of {@link StatsQuery}.
170          */
171         @NonNull
build()172         public StatsQuery build() {
173             return new StatsQuery(sqlDialect, rawSql, minSqlClientVersion, policyConfig);
174         }
175     }
176 }
177