CountersStorageEngine.kt 2.55 KB
Newer Older
1
2
3
4
5
6
7
/* 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/. */

package mozilla.components.service.glean.storages

import android.annotation.SuppressLint
8
import android.content.SharedPreferences
9
10
import mozilla.components.service.glean.error.ErrorRecording.recordError
import mozilla.components.service.glean.error.ErrorRecording.ErrorType
11
import mozilla.components.service.glean.private.CommonMetricData
12
13
14
15
import mozilla.components.support.base.log.logger.Logger

/**
 * This singleton handles the in-memory storage logic for counters. It is meant to be used by
16
 * the Specific Counters API and the ping assembling objects.
17
18
19
20
21
22
23
24
25
26
 *
 * This class contains a reference to the Android application Context. While the IDE warns
 * us that this could leak, the application context lives as long as the application and this
 * object. For this reason, we should be safe to suppress the IDE warning.
 */
@SuppressLint("StaticFieldLeak")
internal object CountersStorageEngine : CountersStorageEngineImplementation()

internal open class CountersStorageEngineImplementation(
    override val logger: Logger = Logger("glean/CountersStorageEngine")
27
) : GenericStorageEngine<Int>() {
28

29
    override fun deserializeSingleMetric(metricName: String, value: Any?): Int? {
30
31
32
33
34
        return (value as? Int)?.let {
            return@let if (it < 0) null else it
        }
    }

35
36
37
    override fun serializeSingleMetric(
        userPreferences: SharedPreferences.Editor?,
        storeName: String,
38
39
        value: Int,
        extraSerializationData: Any?
40
41
42
43
    ) {
        userPreferences?.putInt(storeName, value)
    }

44
45
46
47
48
49
50
51
52
53
54
    /**
     * Record a string in the desired stores.
     *
     * @param metricData object with metric settings
     * @param amount the integer amount to add to the currently stored value.  If there is
     * no current value, then the amount will be stored as the current value.
     */
    fun record(
        metricData: CommonMetricData,
        amount: Int
    ) {
55
56
57
58
59
60
61
62
63
64
        if (amount <= 0) {
            recordError(
                metricData,
                ErrorType.InvalidValue,
                "Added negative or zero value $amount",
                logger
            )
            return
        }

65
        // Use a custom combiner to add the amount to the existing counters rather than overwriting
66
        super.recordMetric(metricData, amount, null) { currentValue, newAmount ->
67
            currentValue?.let { it + newAmount } ?: newAmount
68
69
70
        }
    }
}