DatetimeMetricType.kt 5.5 KB
Newer Older
1
2
3
4
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

5
package mozilla.components.service.glean.private
6
7

import android.support.annotation.VisibleForTesting
travis79's avatar
travis79 committed
8
import mozilla.components.service.glean.Dispatchers
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import mozilla.components.service.glean.storages.DatetimesStorageEngine
import mozilla.components.service.glean.utils.parseISOTimeString
import mozilla.components.support.base.log.logger.Logger
import java.util.Calendar
import java.util.Date

/**
 * This implements the developer facing API for recording datetime metrics.
 *
 * Instances of this class type are automatically generated by the parsers at build time,
 * allowing developers to record values that were previously registered in the metrics.yaml file.
 */
data class DatetimeMetricType(
    override val disabled: Boolean,
    override val category: String,
    override val lifetime: Lifetime,
    override val name: String,
    override val sendInPings: List<String>,
27
    val timeUnit: TimeUnit = TimeUnit.Minute
28
29
30
31
32
33
34
) : CommonMetricData {

    override val defaultStorageDestinations: List<String> = listOf("metrics")

    private val logger = Logger("glean/DatetimeMetricType")

    /**
35
     * Set a datetime value, truncating it to the metric's resolution.
36
37
38
39
40
41
42
43
     *
     * @param value The [Date] value to set. If not provided, will record the current time.
     */
    fun set(value: Date = Date()) {
        if (!shouldRecord(logger)) {
            return
        }

44
        @Suppress("EXPERIMENTAL_API_USAGE")
45
        Dispatchers.API.launch {
46
47
48
            // Delegate storing the datetime to the storage engine.
            DatetimesStorageEngine.set(
                this@DatetimeMetricType,
49
                value
50
51
52
53
54
            )
        }
    }

    /**
55
     * Set a datetime value, truncating it to the metric's resolution.
56
57
58
59
60
61
62
     *
     * This is provided as an internal-only function so that we can test that timezones
     * are passed through correctly.  The normal public interface uses [Date] objects which
     * are always in the local timezone.
     *
     * @param value The [Calendar] value to set. If not provided, will record the current time.
     */
63
    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
64
65
66
67
68
    internal fun set(value: Calendar) {
        if (!shouldRecord(logger)) {
            return
        }

69
        @Suppress("EXPERIMENTAL_API_USAGE")
70
        Dispatchers.API.launch {
71
72
73
            // Delegate storing the datetime to the storage engine.
            DatetimesStorageEngine.set(
                this@DatetimeMetricType,
74
                value
75
76
77
78
79
            )
        }
    }

    /**
80
81
82
     * Tests whether a value is stored for the metric for testing purposes only. This function will
     * attempt to await the last task (if any) writing to the the metric's storage engine before
     * returning a value.
83
84
85
86
87
88
89
90
     *
     * @param pingName represents the name of the ping to retrieve the metric for.  Defaults
     *                 to the either the first value in [defaultStorageDestinations] or the first
     *                 value in [sendInPings]
     * @return true if metric value exists, otherwise false
     */
    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
    fun testHasValue(pingName: String = getStorageNames().first()): Boolean {
91
        @Suppress("EXPERIMENTAL_API_USAGE")
92
        Dispatchers.API.assertInTestingMode()
93

94
95
96
97
        return DatetimesStorageEngine.getSnapshot(pingName, false)?.get(identifier) != null
    }

    /**
98
99
100
     * Returns the string representation of the stored value for testing purposes only. This
     * function will attempt to await the last task (if any) writing to the the metric's storage
     * engine before returning a value.
101
102
103
104
105
106
107
108
109
     *
     * @param pingName represents the name of the ping to retrieve the metric for.  Defaults
     *                 to the either the first value in [defaultStorageDestinations] or the first
     *                 value in [sendInPings]
     * @return value of the stored metric
     * @throws [NullPointerException] if no value is stored
     */
    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
    fun testGetValueAsString(pingName: String = getStorageNames().first()): String {
110
        @Suppress("EXPERIMENTAL_API_USAGE")
111
        Dispatchers.API.assertInTestingMode()
112

113
114
115
116
        return DatetimesStorageEngine.getSnapshot(pingName, false)!![identifier]!!
    }

    /**
117
118
     * Returns the stored value for testing purposes only. This function will attempt to await the
     * last task (if any) writing to the the metric's storage engine before returning a value.
119
120
121
122
123
124
125
126
127
128
129
130
131
     *
     * [Date] objects are always in the user's local timezone offset. If you
     * care about checking that the timezone offset was set and sent correctly, use
     * [testGetValueAsString] and inspect the offset.
     *
     * @param pingName represents the name of the ping to retrieve the metric for.  Defaults
     *                 to the either the first value in [defaultStorageDestinations] or the first
     *                 value in [sendInPings]
     * @return value of the stored metric
     * @throws [NullPointerException] if no value is stored
     */
    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
    fun testGetValue(pingName: String = getStorageNames().first()): Date {
132
        @Suppress("EXPERIMENTAL_API_USAGE")
133
        Dispatchers.API.assertInTestingMode()
134

135
136
137
        return parseISOTimeString(DatetimesStorageEngine.getSnapshot(pingName, false)!![identifier]!!)!!
    }
}