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

Commit 9a56c44e authored by George Lin's avatar George Lin Committed by Android (Google) Code Review
Browse files

Merge "[TP] Clock carousel view" into tm-qpr-dev

parents cbad0d9b 8d3ba609
Loading
Loading
Loading
Loading
+102 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2023 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.
-->
<androidx.constraintlayout.motion.widget.MotionLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/motion_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layoutDescription="@xml/carousel_scene">

    <FrameLayout
        android:id="@+id/item_view_0"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginEnd="16dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/item_view_1"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@+id/item_view_1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginEnd="16dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/item_view_2"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@+id/item_view_2"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@+id/item_view_3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginStart="16dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/item_view_2"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@+id/item_view_4"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginStart="16dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/item_view_3"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.helper.widget.Carousel
        android:id="@+id/carousel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:carousel_backwardTransition="@+id/backward"
        app:carousel_firstView="@+id/item_view_2"
        app:carousel_forwardTransition="@+id/forward"
        app:carousel_infinite="true"
        app:carousel_nextState="@+id/next"
        app:carousel_previousState="@+id/previous"
        app:constraint_referenced_ids="item_view_0,item_view_1,item_view_2,item_view_3,item_view_4" />

    <!-- The guidelines make sure that only the view in the middle show between the lines  -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="100dp" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline_end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_end="100dp" />
</androidx.constraintlayout.motion.widget.MotionLayout>
 No newline at end of file
+35 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2023 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/section_header_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <include layout="@layout/section_header" />
    </FrameLayout>

    <com.android.customization.picker.clock.ui.view.ClockCarouselView
        android:id="@+id/image_carousel_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
 No newline at end of file
+133 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2023 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.
-->
<MotionScene
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetStart="@id/start"
        motion:constraintSetEnd="@+id/next"
        motion:duration="1000"
        android:id="@+id/forward">
        <OnSwipe
            motion:dragDirection="dragLeft"
            motion:touchAnchorSide="left" />
    </Transition>

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/previous"
        android:id="@+id/backward">
        <OnSwipe
            motion:dragDirection="dragRight"
            motion:touchAnchorSide="right" />
    </Transition>

    <ConstraintSet android:id="@+id/previous">
        <Constraint
            android:id="@+id/item_view_0"
            android:layout_width="100dp"
            android:layout_height="100dp"
            motion:layout_constraintEnd_toStartOf="@id/guideline_start"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginEnd="16dp" />
        <Constraint
            android:id="@+id/item_view_1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintHorizontal_bias="0.5"
            motion:layout_constraintStart_toStartOf="@id/guideline_start"
            motion:layout_constraintEnd_toEndOf="@id/guideline_end"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp" />
        <Constraint
            android:id="@+id/item_view_2"
            android:layout_width="100dp"
            android:layout_height="100dp"
            motion:layout_constraintStart_toStartOf="@id/guideline_end"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginStart="16dp" />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/item_view_1"
            android:layout_width="100dp"
            android:layout_height="100dp"
            motion:layout_constraintEnd_toStartOf="@id/guideline_start"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginEnd="16dp" />
        <Constraint
            android:id="@+id/item_view_2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintHorizontal_bias="0.5"
            motion:layout_constraintStart_toStartOf="@id/guideline_start"
            motion:layout_constraintEnd_toEndOf="@id/guideline_end"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp" />
        <Constraint
            android:id="@+id/item_view_3"
            android:layout_width="100dp"
            android:layout_height="100dp"
            motion:layout_constraintStart_toStartOf="@id/guideline_end"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginStart="16dp" />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/next">
        <Constraint
            android:id="@+id/item_view_2"
            android:layout_width="100dp"
            android:layout_height="100dp"
            motion:layout_constraintEnd_toStartOf="@id/guideline_start"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginEnd="16dp" />
        <Constraint
            android:id="@+id/item_view_3"
            android:layout_width="0dp"
            android:layout_height="0dp"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintHorizontal_bias="0.5"
            motion:layout_constraintStart_toStartOf="@id/guideline_start"
            motion:layout_constraintEnd_toEndOf="@id/guideline_end"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp" />
        <Constraint
            android:id="@+id/item_view_4"
            android:layout_width="100dp"
            android:layout_height="100dp"
            motion:layout_constraintStart_toStartOf="@id/guideline_end"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginStart="16dp" />
    </ConstraintSet>

</MotionScene>
 No newline at end of file
+5 −1
Original line number Diff line number Diff line
@@ -25,9 +25,13 @@ import kotlinx.coroutines.flow.Flow
 * clocks.
 */
interface ClockPickerRepository {
    val selectedClock: Flow<ClockMetadataModel?>
    val allClocks: Array<ClockMetadataModel>

    val selectedClock: Flow<ClockMetadataModel>

    val selectedClockSize: Flow<ClockSize>

    fun setSelectedClock(clockId: String)

    fun setClockSize(size: ClockSize)
}
+14 −10
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
 */
package com.android.customization.picker.clock.data.repository

import android.util.Log
import com.android.customization.picker.clock.shared.ClockSize
import com.android.customization.picker.clock.shared.model.ClockMetadataModel
import com.android.systemui.plugins.ClockMetadata
@@ -28,19 +27,24 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.callbackFlow

/** Implementation of [ClockPickerRepository], using [ClockRegistry]. */
class ClockPickerRepositoryImpl(registry: ClockRegistry) : ClockPickerRepository {
class ClockPickerRepositoryImpl(private val registry: ClockRegistry) : ClockPickerRepository {

    override val allClocks: Array<ClockMetadataModel> =
        registry
            .getClocks()
            .filter { "NOT_IN_USE" !in it.clockId }
            .map { it.toModel() }
            .toTypedArray()

    /** The currently-selected clock. */
    override val selectedClock: Flow<ClockMetadataModel?> = callbackFlow {
    override val selectedClock: Flow<ClockMetadataModel> = callbackFlow {
        fun send() {
            val model =
                registry
                    .getClocks()
                    .find { clockMetadata -> clockMetadata.clockId == registry.currentClockId }
                    ?.toModel()
            if (model == null) {
                Log.e(TAG, "Currently selected clock ID is not one of the available clocks.")
            }
            checkNotNull(model)
            trySend(model)
        }

@@ -50,6 +54,10 @@ class ClockPickerRepositoryImpl(registry: ClockRegistry) : ClockPickerRepository
        awaitClose { registry.unregisterClockChangeListener(listener) }
    }

    override fun setSelectedClock(clockId: String) {
        registry.currentClockId = clockId
    }

    // TODO(b/262924055): Use the shared system UI component to query the clock size
    private val _selectedClockSize = MutableStateFlow(ClockSize.DYNAMIC)
    override val selectedClockSize: Flow<ClockSize> = _selectedClockSize.asStateFlow()
@@ -61,8 +69,4 @@ class ClockPickerRepositoryImpl(registry: ClockRegistry) : ClockPickerRepository
    private fun ClockMetadata.toModel(): ClockMetadataModel {
        return ClockMetadataModel(clockId = clockId, name = name)
    }

    companion object {
        private const val TAG = "ClockPickerRepositoryImpl"
    }
}
Loading