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

Commit 621623e7 authored by George Lin's avatar George Lin
Browse files

Grid customiztion screen (1/2)

Test: Manually tested. See bug.
Bug: 362237825
Flag: com.android.systemui.shared.new_customization_picker_ui
Change-Id: I717112c9aa40a8deee4ddd1890d23738b8c75998
parent 82821cb4
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@
        android:text="@string/grid_title"
        android:layout_marginEnd="@dimen/customization_option_entry_text_margin_end"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/option_entry_app_grid_icon"
        app:layout_constraintEnd_toStartOf="@+id/option_entry_app_grid_icon_container"
        app:layout_constraintBottom_toTopOf="@+id/option_entry_app_grid_description"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed" />
@@ -42,19 +42,25 @@
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="@dimen/customization_option_entry_text_margin_end"
        android:text="4x4"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/option_entry_app_grid_icon"
        app:layout_constraintEnd_toStartOf="@+id/option_entry_app_grid_icon_container"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/option_entry_app_grid_title" />

    <FrameLayout
        android:id="@+id/option_entry_app_grid_icon"
        android:id="@+id/option_entry_app_grid_icon_container"
        android:layout_width="@dimen/customization_option_entry_icon_size"
        android:layout_height="@dimen/customization_option_entry_icon_size"
        android:orientation="horizontal"
        android:padding="@dimen/customization_option_entry_icon_padding"
        android:background="@drawable/customization_option_entry_icon_background"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />
        app:layout_constraintBottom_toBottomOf="parent">

        <ImageView
            android:id="@+id/option_entry_app_grid_icon"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:contentDescription="@string/grid_preview_card_content_description" />
    </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+54 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?><!--
  ~ Copyright (C) 2024 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingHorizontal="@dimen/floating_sheet_horizontal_padding"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingVertical="@dimen/floating_sheet_content_vertical_padding"
        android:background="@drawable/floating_sheet_content_background"
        android:clipToPadding="false"
        android:clipChildren="false">

        <!--
        This is just an invisible placeholder put in place so that the parent keeps its height
        stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows the
        layout logic to keep the size of the preview container stable as well, which bodes well
        for setting up the SurfaceView for remote rendering without changing its size after the
        content is loaded into the RecyclerView.

        It's critical for any TextViews inside the included layout to have text.
        -->
        <include
            layout="@layout/grid_option"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="invisible" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@id/options"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:clipToPadding="false"
            android:clipChildren="false" />
    </FrameLayout>
</LinearLayout>
 No newline at end of file
+94 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.customization.model.grid

import android.content.ContentValues
import android.content.Context
import com.android.wallpaper.R
import com.android.wallpaper.picker.di.modules.BackgroundDispatcher
import com.android.wallpaper.util.PreviewUtils
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext

@Singleton
class DefaultGridOptionsManager
@Inject
constructor(
    @ApplicationContext private val context: Context,
    @BackgroundDispatcher private val bgDispatcher: CoroutineDispatcher,
) : GridOptionsManager2 {

    private val authorityMetadataKey: String =
        context.getString(R.string.grid_control_metadata_name)
    private val previewUtils: PreviewUtils = PreviewUtils(context, authorityMetadataKey)

    override suspend fun isGridOptionAvailable(): Boolean {
        return previewUtils.supportsPreview() && (getGridOptions()?.size ?: 0) > 1
    }

    override suspend fun getGridOptions(): List<GridOptionModel>? =
        withContext(bgDispatcher) {
            context.contentResolver
                .query(previewUtils.getUri(LIST_OPTIONS), null, null, null, null)
                ?.use { cursor ->
                    buildList {
                        while (cursor.moveToNext()) {
                            val rows = cursor.getInt(cursor.getColumnIndex(COL_ROWS))
                            val cols = cursor.getInt(cursor.getColumnIndex(COL_COLS))
                            add(
                                GridOptionModel(
                                    key = cursor.getString(cursor.getColumnIndex(COL_NAME)),
                                    title =
                                        context.getString(
                                            com.android.themepicker.R.string.grid_title_pattern,
                                            cols,
                                            rows
                                        ),
                                    isCurrent =
                                        cursor
                                            .getString(cursor.getColumnIndex(COL_IS_DEFAULT))
                                            .toBoolean(),
                                    rows = rows,
                                    cols = cols,
                                )
                            )
                        }
                    }
                }
        }

    override fun applyGridOption(gridName: String): Int {
        return context.contentResolver.update(
            previewUtils.getUri(DEFAULT_GRID),
            ContentValues().apply { put("name", gridName) },
            null,
            null,
        )
    }

    companion object {
        const val LIST_OPTIONS: String = "list_options"
        const val DEFAULT_GRID: String = "default_grid"
        const val COL_NAME: String = "name"
        const val COL_ROWS: String = "rows"
        const val COL_COLS: String = "cols"
        const val COL_IS_DEFAULT: String = "is_default"
    }
}
+25 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.customization.model.grid

data class GridOptionModel(
    val key: String,
    val title: String,
    val isCurrent: Boolean,
    val rows: Int,
    val cols: Int,
)
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.customization.model.grid

interface GridOptionsManager2 {

    suspend fun isGridOptionAvailable(): Boolean

    suspend fun getGridOptions(): List<GridOptionModel>?

    fun applyGridOption(gridName: String): Int
}
Loading