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

Commit 82965df8 authored by Michel Comin Escude's avatar Michel Comin Escude
Browse files

Fix Weather Engine loading

(original cl: go/aux-gerrit/21340)

There were a several issues with the current implementation
of the WeatherEngine:
- We were not loading/saving the last weather. That made that
if the wallpaper is set and we boot the device, we don't have
a weather and thus we did not show anything.
- Assets loading were set in onResume. This caused a bunch of issues,
from not loading the assets to not having a preview of the wallpaper
(because the picker pauses and stops the wallpaper several time while
getting it ready to preview, thus the asset loading was
being cancelled).
- Not having a thumbnail was causing a crash on the picker.
- Moved the stopping of the loading job to onDestroy (for same
reason as stated before).
- First time debug activity was loaded it had missing wallpaper.
- Fixed issue with framebuffer.
- Intensity setting was not visible.

Flag: EXEMPT MP apk not in build yet
Bug: 352352241
Test: visual
Change-Id: I70770b26fdad69d48c86efe1adf0e0fbd946e954
parent 4f5de683
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -100,10 +100,20 @@
            android:text="@string/set_wallpaper"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintBottom_toBottomOf="@id/seekBar"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginBottom="30dp"
            android:layout_marginEnd="20dp" />

        <SeekBar
            android:id="@+id/seekBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:max="100"
            android:progress="80"
            android:layout_marginBottom="50dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>
    </androidx.constraintlayout.widget.ConstraintLayout>

</FrameLayout>
+33 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.view.SurfaceView
import android.view.View
import android.widget.Button
import android.widget.FrameLayout
import android.widget.SeekBar
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.google.android.torus.core.activity.TorusViewerActivity
@@ -36,9 +37,10 @@ import com.google.android.torus.core.engine.TorusEngine
import com.google.android.torus.utils.extensions.setImmersiveFullScreen
import com.google.android.wallpaper.weathereffects.dagger.BackgroundScope
import com.google.android.wallpaper.weathereffects.dagger.MainScope
import com.google.android.wallpaper.weathereffects.data.repository.WallpaperFileUtils
import com.google.android.wallpaper.weathereffects.domain.WeatherEffectsInteractor
import com.google.android.wallpaper.weathereffects.provider.WallpaperInfoContract
import com.google.android.wallpaper.weathereffects.shared.model.WallpaperFileModel
import com.google.android.wallpaper.weathereffects.domain.WeatherEffectsInteractor
import java.io.File
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -66,6 +68,9 @@ class WallpaperEffectsDebugActivity : TorusViewerActivity() {
    private val fgCachedAssetPaths: ArrayList<String> = arrayListOf()
    private val bgCachedAssetPaths: ArrayList<String> = arrayListOf()

    /** It will be initialized on [onCreate]. */
    private var intensity: Float = 0.8f

    override fun getWallpaperEngine(context: Context, surfaceView: SurfaceView): TorusEngine {
        this.surfaceView = surfaceView
        val engine = WeatherEngine(surfaceView.holder, mainScope, interactor, context)
@@ -140,6 +145,27 @@ class WallpaperEffectsDebugActivity : TorusViewerActivity() {
            }

        setDebugText()
        val seekBar = rootView.requireViewById<SeekBar>(R.id.seekBar)
        seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                // Convert progress to a value between 0 and 1
                val value = progress.toFloat() / 100f
                engine?.setIntensity(value)
                intensity = value
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
                hideButtons()
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                showButtons()
            }
        })
        intensity = seekBar.progress.toFloat() / 100f

        // This avoids that the initial state after installing is showing a black screen.
        if (!WallpaperFileUtils.hasBitmapsInLocalStorage(applicationContext)) updateWallpaper()
    }

    private fun writeAssetsToCache() {
@@ -190,8 +216,11 @@ class WallpaperEffectsDebugActivity : TorusViewerActivity() {
                    weatherEffect,
                )
            )
            setDebugText("Wallpaper updated successfully.\n* Weather: " +
                    "$weatherEffect\n* Foreground: $fgPath\n* Background: $bgPath")
            engine?.setIntensity(intensity)
            setDebugText(
                "Wallpaper updated successfully.\n* Weather: " +
                        "$weatherEffect\n* Foreground: $fgPath\n* Background: $bgPath"
            )
        }
    }

+4 −2
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ class FrameBuffer(width: Int, height: Int, format: Int = HardwareBuffer.RGBA_888
        renderer.obtainRenderRequest().setColorSpace(colorSpace).draw(executor) { result ->
            if (result.status == HardwareBufferRenderer.RenderResult.SUCCESS) {
                result.fence.await(Duration.ofMillis(RESULT_FENCE_TIME_OUT))
                if (!buffer.isClosed) {
                    if (!buffer.isClosed) {
                        Bitmap.wrapHardwareBuffer(buffer, colorSpace)?.let {
                            callbackExecutor.execute { onImageReady.invoke(it) }
@@ -94,6 +95,7 @@ class FrameBuffer(width: Int, height: Int, format: Int = HardwareBuffer.RGBA_888
                }
            }
        }
    }

    /**
     * Configure the [FrameBuffer] to apply to this RenderNode. This will apply a visual effect to
+1 −0
Original line number Diff line number Diff line
@@ -18,4 +18,5 @@
    android:author="@string/google_author"
    android:description="@string/wallpaper_description"
    android:showMetadataInPreview="true"
    android:thumbnail="@drawable/ic_launcher_foreground"
    android:supportsAmbientMode="false"/>
+57 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Log
import com.google.android.wallpaper.weathereffects.provider.WallpaperInfoContract
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -35,7 +36,7 @@ object WallpaperFileUtils {
     * @param dispatcher the dispatcher to run within.
     * @return `true` when exported successfully
     */
    suspend fun export(
    suspend fun exportBitmap(
        context: Context,
        fileName: String,
        bitmap: Bitmap,
@@ -122,6 +123,59 @@ object WallpaperFileUtils {
        }
    }

    /**
     * Exports the last known weather, and saves it into a shared preferences file. This is
     * needed so when we reboot the device, we have information about the last weather and we can
     * show it (also so we don't have to wait for the weather API to fetch the current weather).
     *
     * @param weatherEffect the last known weather effect.
     * @param context the [Context] of the caller.
     */
    fun exportLastKnownWeather(
        weatherEffect: WallpaperInfoContract.WeatherEffect,
        context: Context
    ) {
        asProtectedContext(context).getSharedPreferences(PREF_FILENAME, Context.MODE_PRIVATE)
            .edit()
            .putString(LAST_KNOWN_WEATHER_KEY, weatherEffect.value)
            .apply()
    }

    /**
     * Imports the last known weather from shared preferences.
     *
     * @param context the [Context] of the caller
     *
     * @return the last known weather effect, or null if not found
     */
    fun importLastKnownWeather(context: Context): WallpaperInfoContract.WeatherEffect? {
        return WallpaperInfoContract.WeatherEffect.fromStringValue(
            asProtectedContext(context).getSharedPreferences(
                PREF_FILENAME,
                Context.MODE_PRIVATE
            ).getString(LAST_KNOWN_WEATHER_KEY, null)
        )
    }

    /**
     * Checks if we have Foreground and Background Bitmap in local storage.
     *
     * @param context the [Context] of the caller
     *
     * @return whether both Bitmaps exists
     */
    fun hasBitmapsInLocalStorage(context: Context): Boolean {
        val protectedContext = if (context.isDeviceProtectedStorage) {
            context
        } else {
            context.createDeviceProtectedStorageContext()
        }
        val fileBgd = protectedContext.getFileStreamPath(BG_FILE_NAME)
        val fileFgd = protectedContext.getFileStreamPath(FG_FILE_NAME)

        return fileBgd.exists() && fileFgd.exists()
    }

    private fun asProtectedContext(context: Context): Context {
        return if (context.isDeviceProtectedStorage) {
            context
@@ -133,4 +187,6 @@ object WallpaperFileUtils {
    private const val TAG = "WallpaperFileUtils"
    const val FG_FILE_NAME = "fg_image"
    const val BG_FILE_NAME = "bg_image"
    private const val PREF_FILENAME = "weather_preferences"
    private const val LAST_KNOWN_WEATHER_KEY = "last_known_weather"
}
Loading