1 /*
2  * Copyright 2017 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.privacy.internal.longitudinalreporting;
18 
19 import android.privacy.DifferentialPrivacyConfig;
20 import android.privacy.internal.rappor.RapporConfig;
21 import android.text.TextUtils;
22 
23 import com.android.internal.util.Preconditions;
24 
25 /**
26  * A class to store {@link LongitudinalReportingEncoder} configuration.
27  *
28  * <ul>
29  * <li> f is probability to flip input value, used in IRR.
30  * <li> p is probability to override input value, used in PRR1.
31  * <li> q is probability to set input value as 1 when result of PRR(p) is true, used in PRR2.
32  * </ul>
33  *
34  * @hide
35  */
36 public class LongitudinalReportingConfig implements DifferentialPrivacyConfig {
37 
38     private static final String ALGORITHM_NAME = "LongitudinalReporting";
39 
40     // Probability to flip input value.
41     private final double mProbabilityF;
42 
43     // Probability to override original value.
44     private final double mProbabilityP;
45     // Probability to override value with 1.
46     private final double mProbabilityQ;
47 
48     // IRR config to randomize original value
49     private final RapporConfig mIRRConfig;
50 
51     private final String mEncoderId;
52 
53     /**
54      * Constructor to create {@link LongitudinalReportingConfig} used for {@link
55      * LongitudinalReportingEncoder}
56      *
57      * @param encoderId    Unique encoder id.
58      * @param probabilityF Probability F used in Longitudinal Reporting algorithm.
59      * @param probabilityP Probability P used in Longitudinal Reporting algorithm. This will be
60      *                     quantized to the nearest 1/256.
61      * @param probabilityQ Probability Q used in Longitudinal Reporting algorithm. This will be
62      *                     quantized to the nearest 1/256.
63      */
LongitudinalReportingConfig(String encoderId, double probabilityF, double probabilityP, double probabilityQ)64     public LongitudinalReportingConfig(String encoderId, double probabilityF,
65             double probabilityP, double probabilityQ) {
66         Preconditions.checkArgument(probabilityF >= 0 && probabilityF <= 1,
67                 "probabilityF must be in range [0.0, 1.0]");
68         this.mProbabilityF = probabilityF;
69         Preconditions.checkArgument(probabilityP >= 0 && probabilityP <= 1,
70                 "probabilityP must be in range [0.0, 1.0]");
71         this.mProbabilityP = probabilityP;
72         Preconditions.checkArgument(probabilityQ >= 0 && probabilityQ <= 1,
73                 "probabilityQ must be in range [0.0, 1.0]");
74         this.mProbabilityQ = probabilityQ;
75         Preconditions.checkArgument(!TextUtils.isEmpty(encoderId), "encoderId cannot be empty");
76         mEncoderId = encoderId;
77         mIRRConfig = new RapporConfig(encoderId, 1, 0.0, probabilityF, 1 - probabilityF, 1, 1);
78     }
79 
80     @Override
getAlgorithm()81     public String getAlgorithm() {
82         return ALGORITHM_NAME;
83     }
84 
getIRRConfig()85     RapporConfig getIRRConfig() {
86         return mIRRConfig;
87     }
88 
getProbabilityP()89     double getProbabilityP() {
90         return mProbabilityP;
91     }
92 
getProbabilityQ()93     double getProbabilityQ() {
94         return mProbabilityQ;
95     }
96 
getEncoderId()97     String getEncoderId() {
98         return mEncoderId;
99     }
100 
101     @Override
toString()102     public String toString() {
103         return String.format("EncoderId: %s, ProbabilityF: %.3f, ProbabilityP: %.3f"
104                         + ", ProbabilityQ: %.3f",
105                 mEncoderId, mProbabilityF, mProbabilityP, mProbabilityQ);
106     }
107 }
108