Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1bd2b79b authored by Peter Kalauskas's avatar Peter Kalauskas
Browse files

Read weather data from smartspace

Enable the flag to write mock data using:

  adb shell device_config put device_personalization_services \
      EchoSmartspace__enable_mock_weather_data true

Then, set the icon enum (represented as an int) using:

  adb shell device_config put device_personalization_services \
      EchoSmartspace__mock_weather_state_icon_id 2

Set the temperature (int) using:

  adb shell device_config put device_personalization_services \
      EchoSmartspace__mock_temperature_value 22

Set the temperature unit (boolean) for isCelsius using:

  adb shell device_config put device_personalization_services \
      EchoSmartspace__mock_temperature_unit false

Test: Use device_config commands to test mock data
Bug: 265069396
Change-Id: Ibb110c324f3eb21c0c4fba70b2da5f0c042e9cff
parent 5f3bb108
Loading
Loading
Loading
Loading
+85 −0
Original line number Original line Diff line number Diff line
package com.android.systemui.statusbar

import android.os.Bundle

class Weather(val conditions: WeatherStateIcon, val temperature: Int, val isCelsius: Boolean) {
    companion object {
        private const val TAG = "Weather"
        private const val WEATHER_STATE_ICON_KEY = "weather_state_icon_extra_key"
        private const val TEMPERATURE_VALUE_KEY = "temperature_value_extra_key"
        private const val TEMPERATURE_UNIT_KEY = "temperature_unit_extra_key"
        private const val INVALID_TEMPERATURE = Int.MIN_VALUE

        fun fromBundle(extras: Bundle): Weather? {
            val icon =
                WeatherStateIcon.fromInt(
                    extras.getInt(WEATHER_STATE_ICON_KEY, WeatherStateIcon.UNKNOWN_ICON.id)
                )
            if (icon == null || icon == WeatherStateIcon.UNKNOWN_ICON) {
                return null
            }
            val temperature = extras.getInt(TEMPERATURE_VALUE_KEY, INVALID_TEMPERATURE)
            if (temperature == INVALID_TEMPERATURE) {
                return null
            }
            return Weather(icon, temperature, extras.getBoolean(TEMPERATURE_UNIT_KEY))
        }
    }

    enum class WeatherStateIcon(val id: Int) {
        UNKNOWN_ICON(0),

        // Clear, day & night.
        SUNNY(1),
        CLEAR_NIGHT(2),

        // Mostly clear, day & night.
        MOSTLY_SUNNY(3),
        MOSTLY_CLEAR_NIGHT(4),

        // Partly cloudy, day & night.
        PARTLY_CLOUDY(5),
        PARTLY_CLOUDY_NIGHT(6),

        // Mostly cloudy, day & night.
        MOSTLY_CLOUDY_DAY(7),
        MOSTLY_CLOUDY_NIGHT(8),
        CLOUDY(9),
        HAZE_FOG_DUST_SMOKE(10),
        DRIZZLE(11),
        HEAVY_RAIN(12),
        SHOWERS_RAIN(13),

        // Scattered showers, day & night.
        SCATTERED_SHOWERS_DAY(14),
        SCATTERED_SHOWERS_NIGHT(15),

        // Isolated scattered thunderstorms, day & night.
        ISOLATED_SCATTERED_TSTORMS_DAY(16),
        ISOLATED_SCATTERED_TSTORMS_NIGHT(17),
        STRONG_TSTORMS(18),
        BLIZZARD(19),
        BLOWING_SNOW(20),
        FLURRIES(21),
        HEAVY_SNOW(22),

        // Scattered snow showers, day & night.
        SCATTERED_SNOW_SHOWERS_DAY(23),
        SCATTERED_SNOW_SHOWERS_NIGHT(24),
        SNOW_SHOWERS_SNOW(25),
        MIXED_RAIN_HAIL_RAIN_SLEET(26),
        SLEET_HAIL(27),
        TORNADO(28),
        TROPICAL_STORM_HURRICANE(29),
        WINDY_BREEZY(30),
        WINTRY_MIX_RAIN_SNOW(31);

        companion object {
            fun fromInt(value: Int) = values().firstOrNull { it.id == value }
        }
    }

    override fun toString(): String {
        return "$conditions $temperature${if (isCelsius) "C" else "F"}"
    }
}
+13 −0
Original line number Original line Diff line number Diff line
@@ -53,11 +53,13 @@ import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.regionsampling.RegionSampler
import com.android.systemui.shared.regionsampling.RegionSampler
import com.android.systemui.shared.regionsampling.UpdateColorCallback
import com.android.systemui.shared.regionsampling.UpdateColorCallback
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.WEATHER_SMARTSPACE_DATA_PLUGIN
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.WEATHER_SMARTSPACE_DATA_PLUGIN
import com.android.systemui.statusbar.Weather
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.util.concurrency.Execution
import com.android.systemui.util.concurrency.Execution
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.settings.SecureSettings
import java.time.Instant
import java.util.Optional
import java.util.Optional
import java.util.concurrent.Executor
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Inject
@@ -160,7 +162,18 @@ constructor(
            }
            }
            isContentUpdatedOnce = true
            isContentUpdatedOnce = true
        }
        }

        val now = Instant.now()
        val weatherTarget = targets.find { t ->
            t.featureType == SmartspaceTarget.FEATURE_WEATHER &&
                    now.isAfter(Instant.ofEpochMilli(t.creationTimeMillis)) &&
                    now.isBefore(Instant.ofEpochMilli(t.expiryTimeMillis))
        }
        if (weatherTarget != null) {
            val weatherData = Weather.fromBundle(weatherTarget.baseAction.extras)
        }
        }
    }



    private val userTrackerCallback = object : UserTracker.Callback {
    private val userTrackerCallback = object : UserTracker.Callback {
        override fun onUserChanged(newUser: Int, userContext: Context) {
        override fun onUserChanged(newUser: Int, userContext: Context) {