1 /*
2  * Copyright (C) 2016 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.settingslib.core.instrumentation;
18 
19 import static com.android.settingslib.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
20 
21 import android.app.Activity;
22 import android.content.Intent;
23 import android.os.SystemClock;
24 
25 import androidx.lifecycle.Lifecycle.Event;
26 import androidx.lifecycle.OnLifecycleEvent;
27 
28 import com.android.internal.logging.nano.MetricsProto;
29 import com.android.settingslib.core.lifecycle.LifecycleObserver;
30 import com.android.settingslib.core.lifecycle.events.OnAttach;
31 
32 /**
33  * Logs visibility change of a fragment.
34  */
35 public class VisibilityLoggerMixin implements LifecycleObserver, OnAttach {
36 
37     private static final String TAG = "VisibilityLoggerMixin";
38 
39     private final int mMetricsCategory;
40 
41     private MetricsFeatureProvider mMetricsFeature;
42     private int mSourceMetricsCategory = MetricsProto.MetricsEvent.VIEW_UNKNOWN;
43     private long mCreationTimestamp;
44     private long mVisibleTimestamp;
45 
VisibilityLoggerMixin(int metricsCategory, MetricsFeatureProvider metricsFeature)46     public VisibilityLoggerMixin(int metricsCategory, MetricsFeatureProvider metricsFeature) {
47         mMetricsCategory = metricsCategory;
48         mMetricsFeature = metricsFeature;
49     }
50 
51     @Override
onAttach()52     public void onAttach() {
53         mCreationTimestamp = SystemClock.elapsedRealtime();
54     }
55 
56     @OnLifecycleEvent(Event.ON_RESUME)
onResume()57     public void onResume() {
58         if (mMetricsFeature == null || mMetricsCategory == METRICS_CATEGORY_UNKNOWN) {
59             return;
60         }
61         mVisibleTimestamp = SystemClock.elapsedRealtime();
62         if (mCreationTimestamp != 0L) {
63             final int elapse = (int) (mVisibleTimestamp - mCreationTimestamp);
64             mMetricsFeature.visible(null /* context */, mSourceMetricsCategory,
65                     mMetricsCategory, elapse);
66         } else {
67             mMetricsFeature.visible(null /* context */, mSourceMetricsCategory,
68                     mMetricsCategory, 0);
69         }
70     }
71 
72     @OnLifecycleEvent(Event.ON_PAUSE)
onPause()73     public void onPause() {
74         mCreationTimestamp = 0;
75         if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
76             final int elapse = (int) (SystemClock.elapsedRealtime() - mVisibleTimestamp);
77             mMetricsFeature.hidden(null /* context */, mMetricsCategory, elapse);
78         }
79     }
80 
81     /**
82      * Logs the elapsed time from onAttach to calling {@link #writeElapsedTimeMetric(int, String)}.
83      * @param action : The value of the Action Enums.
84      * @param key : The value of special key string.
85      */
writeElapsedTimeMetric(int action, String key)86     public void writeElapsedTimeMetric(int action, String key) {
87         if (mMetricsFeature == null || mMetricsCategory == METRICS_CATEGORY_UNKNOWN) {
88             return;
89         }
90         if (mCreationTimestamp != 0L) {
91             final int elapse = (int) (SystemClock.elapsedRealtime() - mCreationTimestamp);
92             mMetricsFeature.action(METRICS_CATEGORY_UNKNOWN, action, mMetricsCategory, key, elapse);
93         }
94     }
95 
96     /**
97      * Sets source metrics category for this logger. Source is the caller that opened this UI.
98      */
setSourceMetricsCategory(Activity activity)99     public void setSourceMetricsCategory(Activity activity) {
100         if (mSourceMetricsCategory != MetricsProto.MetricsEvent.VIEW_UNKNOWN || activity == null) {
101             return;
102         }
103         final Intent intent = activity.getIntent();
104         if (intent == null) {
105             return;
106         }
107         mSourceMetricsCategory = intent.getIntExtra(
108                 MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY,
109                 MetricsProto.MetricsEvent.VIEW_UNKNOWN);
110     }
111 }
112