summaryrefslogtreecommitdiff
path: root/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
blob: 30dbaef24013e0553ac05297d754ba354c9568a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package com.android.systemui.power;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Settings;
import android.util.KeyValueListParser;
import android.util.Log;

import com.android.internal.util.aicp.PackageUtils;
import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.utils.PowerUtil;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.util.settings.GlobalSettings;

import java.time.Duration;

import javax.inject.Inject;

@SysUISingleton
public final class EnhancedEstimatesImpl implements EnhancedEstimates {

    private static final String TAG = "EnhancedEstimatesImpl";

    private static final Estimate EMPTY_ESTIMATE = new Estimate(-1L, false, -1L);

    private static final Duration DAY = Duration.ofDays(1L);
    private static final long HOUR = Duration.ofHours(1L).toMillis();
    private static final long THREE_HOURS = Duration.ofHours(3L).toMillis();
    private static final long FIFTEEN_MINUTES = Duration.ofMinutes(15L).toMillis();

    private final Context mContext;
    private final GlobalSettings mGlobalSettings;
    private final KeyValueListParser mParser;

    @Inject
    public EnhancedEstimatesImpl(
        Context context,
        GlobalSettings globalSettings
    ) {
        mContext = context;
        mGlobalSettings = globalSettings;
        mParser = new KeyValueListParser(',');
    }

    @Override
    public boolean isHybridNotificationEnabled() {
        final boolean isTurboInstalled = PackageUtils.isPackageInstalled(
            mContext,
            "com.google.android.apps.turbo",
            false /* ignoreState */
        );
        if (!isTurboInstalled) return false;
        updateFlags();
        return mParser.getBoolean("hybrid_enabled", true);
    }

    @Override
    public Estimate getEstimate() {
        final Uri build = new Uri.Builder()
            .scheme("content")
            .authority("com.google.android.apps.turbo.estimated_time_remaining")
            .appendPath("time_remaining")
            .build();
        try (final Cursor query = mContext.getContentResolver().query(build, null, null, null, null)) {
            if (query == null) return EMPTY_ESTIMATE;
            try {
                if (query.moveToFirst()) {
                    long timeRemaining = -1L;
                    final int usageColumnIndex = query.getColumnIndex("is_based_on_usage");
                    final boolean isBasedOnUsage = usageColumnIndex != -1 && query.getInt(usageColumnIndex) != 0;
                    final int batteryLifecolumnIndex = query.getColumnIndex("average_battery_life");
                    if (batteryLifecolumnIndex != -1) {
                        final long averageBatteryLife = query.getLong(batteryLifecolumnIndex);
                        if (averageBatteryLife != -1L) {
                            final long duration = Duration.ofMillis(averageBatteryLife).compareTo(DAY) >= 0
                                ? HOUR : FIFTEEN_MINUTES;
                            timeRemaining = PowerUtil.roundTimeToNearestThreshold(averageBatteryLife, duration);
                        }
                    }
                    return new Estimate(
                        query.getLong(query.getColumnIndex("battery_estimate")),
                        isBasedOnUsage,
                        timeRemaining
                    );
                }
            } catch (Exception ex) {
                // Catch and release
            }
        } catch (Exception e) {
            Log.e(TAG, "Something went wrong when getting an estimate from Turbo", e);
        }
        return EMPTY_ESTIMATE;
    }

    @Override
    public long getLowWarningThreshold() {
        updateFlags();
        return mParser.getLong("low_threshold", THREE_HOURS);
    }

    @Override
    public long getSevereWarningThreshold() {
        updateFlags();
        return mParser.getLong("severe_threshold", HOUR);
    }

    @Override
    public boolean getLowWarningEnabled() {
        updateFlags();
        return mParser.getBoolean("low_warning_enabled", false);
    }

    private void updateFlags() {
        final String string = mGlobalSettings.getString("hybrid_sysui_battery_warning_flags");
        try {
            mParser.setString(string);
        } catch (IllegalArgumentException ex) {
            Log.e(TAG, "Bad hybrid sysui warning flags");
        }
    }
}