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.google.android.setupcompat.logging.internal;
18 
19 import static java.lang.annotation.RetentionPolicy.SOURCE;
20 
21 import android.annotation.TargetApi;
22 import android.os.Build.VERSION_CODES;
23 import android.os.PersistableBundle;
24 import androidx.annotation.StringDef;
25 import androidx.annotation.VisibleForTesting;
26 import java.lang.annotation.Retention;
27 
28 /** Uses to log internal event footer button metric */
29 public class FooterBarMixinMetrics {
30   @VisibleForTesting
31   public static final String EXTRA_PRIMARY_BUTTON_VISIBILITY = "PrimaryButtonVisibility";
32 
33   @VisibleForTesting
34   public static final String EXTRA_SECONDARY_BUTTON_VISIBILITY = "SecondaryButtonVisibility";
35 
36   @Retention(SOURCE)
37   @StringDef({
38     FooterButtonVisibility.UNKNOWN,
39     FooterButtonVisibility.VISIBLE_USING_XML,
40     FooterButtonVisibility.VISIBLE,
41     FooterButtonVisibility.VISIBLE_USING_XML_TO_INVISIBLE,
42     FooterButtonVisibility.VISIBLE_TO_INVISIBLE,
43     FooterButtonVisibility.INVISIBLE_TO_VISIBLE,
44     FooterButtonVisibility.INVISIBLE,
45   })
46   @VisibleForTesting
47   public @interface FooterButtonVisibility {
48     String UNKNOWN = "Unknown";
49     String VISIBLE_USING_XML = "VisibleUsingXml";
50     String VISIBLE = "Visible";
51     String VISIBLE_USING_XML_TO_INVISIBLE = "VisibleUsingXml_to_Invisible";
52     String VISIBLE_TO_INVISIBLE = "Visible_to_Invisible";
53     String INVISIBLE_TO_VISIBLE = "Invisible_to_Visible";
54     String INVISIBLE = "Invisible";
55   }
56 
57   @FooterButtonVisibility String primaryButtonVisibility = FooterButtonVisibility.UNKNOWN;
58 
59   @FooterButtonVisibility String secondaryButtonVisibility = FooterButtonVisibility.UNKNOWN;
60 
61   /** Creates a metric object for metric logging */
FooterBarMixinMetrics()62   public FooterBarMixinMetrics() {}
63 
64   /** Gets initial state visibility */
65   @FooterButtonVisibility
getInitialStateVisibility(boolean isVisible, boolean isUsingXml)66   public String getInitialStateVisibility(boolean isVisible, boolean isUsingXml) {
67     @FooterButtonVisibility String visibility;
68 
69     if (isVisible) {
70       visibility =
71           isUsingXml ? FooterButtonVisibility.VISIBLE_USING_XML : FooterButtonVisibility.VISIBLE;
72     } else {
73       visibility = FooterButtonVisibility.INVISIBLE;
74     }
75 
76     return visibility;
77   }
78 
79   /** Saves primary footer button visibility when initial state */
logPrimaryButtonInitialStateVisibility(boolean isVisible, boolean isUsingXml)80   public void logPrimaryButtonInitialStateVisibility(boolean isVisible, boolean isUsingXml) {
81     primaryButtonVisibility =
82         primaryButtonVisibility.equals(FooterButtonVisibility.UNKNOWN)
83             ? getInitialStateVisibility(isVisible, isUsingXml)
84             : primaryButtonVisibility;
85   }
86 
87   /** Saves secondary footer button visibility when initial state */
logSecondaryButtonInitialStateVisibility(boolean isVisible, boolean isUsingXml)88   public void logSecondaryButtonInitialStateVisibility(boolean isVisible, boolean isUsingXml) {
89     secondaryButtonVisibility =
90         secondaryButtonVisibility.equals(FooterButtonVisibility.UNKNOWN)
91             ? getInitialStateVisibility(isVisible, isUsingXml)
92             : secondaryButtonVisibility;
93   }
94 
95   /** Saves footer button visibility when finish state */
updateButtonVisibility( boolean isPrimaryButtonVisible, boolean isSecondaryButtonVisible)96   public void updateButtonVisibility(
97       boolean isPrimaryButtonVisible, boolean isSecondaryButtonVisible) {
98     primaryButtonVisibility =
99         updateButtonVisibilityState(primaryButtonVisibility, isPrimaryButtonVisible);
100     secondaryButtonVisibility =
101         updateButtonVisibilityState(secondaryButtonVisibility, isSecondaryButtonVisible);
102   }
103 
104   @FooterButtonVisibility
updateButtonVisibilityState( @ooterButtonVisibility String originalVisibility, boolean isVisible)105   static String updateButtonVisibilityState(
106       @FooterButtonVisibility String originalVisibility, boolean isVisible) {
107     if (!FooterButtonVisibility.VISIBLE_USING_XML.equals(originalVisibility)
108         && !FooterButtonVisibility.VISIBLE.equals(originalVisibility)
109         && !FooterButtonVisibility.INVISIBLE.equals(originalVisibility)) {
110       throw new IllegalStateException("Illegal visibility state: " + originalVisibility);
111     }
112 
113     if (isVisible && FooterButtonVisibility.INVISIBLE.equals(originalVisibility)) {
114       return FooterButtonVisibility.INVISIBLE_TO_VISIBLE;
115     } else if (!isVisible) {
116       if (FooterButtonVisibility.VISIBLE_USING_XML.equals(originalVisibility)) {
117         return FooterButtonVisibility.VISIBLE_USING_XML_TO_INVISIBLE;
118       } else if (FooterButtonVisibility.VISIBLE.equals(originalVisibility)) {
119         return FooterButtonVisibility.VISIBLE_TO_INVISIBLE;
120       }
121     }
122     return originalVisibility;
123   }
124 
125   /** Returns metrics data for logging */
126   @TargetApi(VERSION_CODES.Q)
getMetrics()127   public PersistableBundle getMetrics() {
128     PersistableBundle persistableBundle = new PersistableBundle();
129     persistableBundle.putString(EXTRA_PRIMARY_BUTTON_VISIBILITY, primaryButtonVisibility);
130     persistableBundle.putString(EXTRA_SECONDARY_BUTTON_VISIBILITY, secondaryButtonVisibility);
131     return persistableBundle;
132   }
133 }
134