Merge "Refactor StatsLogUserEventLogger" into udc-qpr-dev
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bff2d76
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.iml
diff --git a/res/values/config.xml b/res/values/config.xml
index d992bf3..ad81e67 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -19,4 +19,8 @@
     <item type="id" name="option_tile" />
     <!-- ID for the label of an option tile -->
     <item type="id" name="option_label" />
+
+    <!-- ID for the a11y actions on carousel -->
+    <item type="id" name="action_scroll_forward" />
+    <item type="id" name="action_scroll_backward" />
 </resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b7574a3..680947d 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -507,4 +507,22 @@
     [CHAR LIMIT=NONE].
     -->
     <string name="content_description_color_option">Color option <xliff:g name="color_number" example="1">%1$d</xliff:g></string>
+
+    <!--
+    Accessibility label for forward scrolling in the carousel of clock faces.
+    [CHAR LIMIT=128].
+    -->
+    <string name="scroll_forward_and_select">Swipe left to choose a different clock face</string>
+
+    <!--
+    Accessibility label for backward scrolling in the carousel of clock faces.
+    [CHAR LIMIT=128].
+    -->
+    <string name="scroll_backward_and_select">Swipe right to choose a different clock face</string>
+
+    <!--
+    Accessibility label for the carousel of clock faces.
+    [CHAR LIMIT=128].
+    -->
+    <string name="custom_clocks_label">Custom Clocks</string>
 </resources>
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
index be6c6cb..2d22c38 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
@@ -33,6 +33,7 @@
 import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
@@ -146,9 +147,10 @@
             )
             .map { setting -> setting == 1 }
             .map { isDynamic -> if (isDynamic) ClockSize.DYNAMIC else ClockSize.SMALL }
+            .distinctUntilChanged()
             .shareIn(
                 scope = scope,
-                started = SharingStarted.WhileSubscribed(),
+                started = SharingStarted.Eagerly,
                 replay = 1,
             )
 
diff --git a/src/com/android/customization/picker/clock/ui/binder/CarouselAccessibilityDelegate.kt b/src/com/android/customization/picker/clock/ui/binder/CarouselAccessibilityDelegate.kt
new file mode 100644
index 0000000..5e3c26e
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/binder/CarouselAccessibilityDelegate.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ *
+ */
+
+package com.android.customization.picker.clock.ui.binder
+
+import android.content.Context
+import android.os.Bundle
+import android.view.View
+import android.view.accessibility.AccessibilityNodeInfo
+import com.android.wallpaper.R
+
+class CarouselAccessibilityDelegate(
+    private val context: Context,
+    private val scrollForwardCallback: () -> Unit,
+    private val scrollBackwardCallback: () -> Unit
+) : View.AccessibilityDelegate() {
+
+    var contentDescriptionOfSelectedClock = ""
+
+    private val ACTION_SCROLL_BACKWARD = R.id.action_scroll_backward
+    private val ACTION_SCROLL_FORWARD = R.id.action_scroll_forward
+
+    override fun onInitializeAccessibilityNodeInfo(host: View?, info: AccessibilityNodeInfo?) {
+        super.onInitializeAccessibilityNodeInfo(host, info)
+        info?.isScrollable = true
+        info?.addAction(
+            AccessibilityNodeInfo.AccessibilityAction(
+                ACTION_SCROLL_FORWARD,
+                context.getString(R.string.scroll_forward_and_select)
+            )
+        )
+        info?.addAction(
+            AccessibilityNodeInfo.AccessibilityAction(
+                ACTION_SCROLL_BACKWARD,
+                context.getString(R.string.scroll_backward_and_select)
+            )
+        )
+        info?.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS)
+        // We need to specifically set the content description since for some reason the talkback
+        // service does not go to children of the clock carousel in the view hierarchy
+        info?.contentDescription = contentDescriptionOfSelectedClock
+    }
+
+    override fun performAccessibilityAction(host: View?, action: Int, args: Bundle?): Boolean {
+        when (action) {
+            ACTION_SCROLL_BACKWARD -> {
+                scrollBackwardCallback.invoke()
+                return true
+            }
+            ACTION_SCROLL_FORWARD -> {
+                scrollForwardCallback.invoke()
+                return true
+            }
+        }
+        return super.performAccessibilityAction(host, action, args)
+    }
+}
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
index 13c80c8..89fac89 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
@@ -15,6 +15,7 @@
  */
 package com.android.customization.picker.clock.ui.binder
 
+import android.content.Context
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.core.view.isVisible
@@ -27,6 +28,7 @@
 import com.android.customization.picker.clock.ui.view.ClockViewFactory
 import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
 import com.android.wallpaper.R
+import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewClickView
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.launch
 
@@ -34,8 +36,10 @@
 
     @JvmStatic
     fun bind(
+        context: Context,
         carouselView: ClockCarouselView,
         singleClockView: ViewGroup,
+        screenPreviewClickView: ScreenPreviewClickView,
         viewModel: ClockCarouselViewModel,
         clockViewFactory: ClockViewFactory,
         lifecycleOwner: LifecycleOwner,
@@ -43,6 +47,20 @@
     ) {
         carouselView.setClockViewFactory(clockViewFactory)
         clockViewFactory.updateRegionDarkness()
+        val carouselAccessibilityDelegate =
+            CarouselAccessibilityDelegate(
+                context,
+                scrollForwardCallback = {
+                    // Callback code for scrolling forward
+                    carouselView.transitionToNext()
+                },
+                scrollBackwardCallback = {
+                    // Callback code for scrolling backward
+                    carouselView.transitionToPrevious()
+                }
+            )
+        screenPreviewClickView.accessibilityDelegate = carouselAccessibilityDelegate
+
         val singleClockHostView =
             singleClockView.requireViewById<FrameLayout>(R.id.single_clock_host_view)
         lifecycleOwner.lifecycleScope.launch {
@@ -71,6 +89,8 @@
 
                 launch {
                     viewModel.selectedIndex.collect { selectedIndex ->
+                        carouselAccessibilityDelegate.contentDescriptionOfSelectedClock =
+                            carouselView.getContentDescription(selectedIndex)
                         carouselView.setSelectedClockIndex(selectedIndex)
                     }
                 }
diff --git a/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragment.kt b/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragment.kt
deleted file mode 100644
index f138d6a..0000000
--- a/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragment.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.android.customization.picker.clock.ui.fragment
-
-import android.content.Context
-import android.os.Bundle
-import android.util.TypedValue
-import android.view.ContextThemeWrapper
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
-import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import android.widget.FrameLayout
-import android.widget.TextView
-import android.widget.Toast
-import androidx.core.view.setPadding
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.android.customization.module.ThemePickerInjector
-import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.plugins.ClockMetadata
-import com.android.systemui.shared.clocks.ClockRegistry
-import com.android.wallpaper.R
-import com.android.wallpaper.module.InjectorProvider
-import com.android.wallpaper.picker.AppbarFragment
-
-class ClockCustomDemoFragment : AppbarFragment() {
-    @VisibleForTesting lateinit var recyclerView: RecyclerView
-    @VisibleForTesting lateinit var clockRegistry: ClockRegistry
-
-    override fun onCreateView(
-        inflater: LayoutInflater,
-        container: ViewGroup?,
-        savedInstanceState: Bundle?
-    ): View {
-        val view = inflater.inflate(R.layout.fragment_clock_custom_picker_demo, container, false)
-        setUpToolbar(view)
-        clockRegistry =
-            (InjectorProvider.getInjector() as ThemePickerInjector).getClockRegistry(
-                requireContext(),
-            )
-        val listInUse = clockRegistry.getClocks().filter { "NOT_IN_USE" !in it.clockId }
-
-        recyclerView = view.requireViewById(R.id.clock_preview_card_list_demo)
-        recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
-        recyclerView.adapter =
-            ClockRecyclerAdapter(listInUse, requireContext()) {
-                clockRegistry.currentClockId = it.clockId
-                Toast.makeText(context, "${it.name} selected", Toast.LENGTH_SHORT).show()
-            }
-        return view
-    }
-
-    override fun getDefaultTitle(): CharSequence {
-        return getString(R.string.clock_title)
-    }
-
-    internal class ClockRecyclerAdapter(
-        val list: List<ClockMetadata>,
-        val context: Context,
-        val onClockSelected: (ClockMetadata) -> Unit
-    ) : RecyclerView.Adapter<ClockRecyclerAdapter.ViewHolder>() {
-        class ViewHolder(val view: View, val textView: TextView, val onItemClicked: (Int) -> Unit) :
-            RecyclerView.ViewHolder(view) {
-            init {
-                itemView.setOnClickListener { onItemClicked(absoluteAdapterPosition) }
-            }
-        }
-
-        override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
-            val rootView = FrameLayout(viewGroup.context)
-            val textView =
-                TextView(ContextThemeWrapper(viewGroup.context, R.style.SectionTitleTextStyle))
-            textView.setPadding(ITEM_PADDING)
-            rootView.addView(textView)
-            val outValue = TypedValue()
-            context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true)
-            rootView.setBackgroundResource(outValue.resourceId)
-            val lp = RecyclerView.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
-            rootView.layoutParams = lp
-            return ViewHolder(rootView, textView) { onClockSelected(list[it]) }
-        }
-
-        override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
-            viewHolder.textView.text = list[position].name
-        }
-
-        override fun getItemCount() = list.size
-
-        companion object {
-            val ITEM_PADDING = 40
-        }
-    }
-}
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
index 73d5508..8764e54 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -16,6 +16,7 @@
 package com.android.customization.picker.clock.ui.view
 
 import android.content.Context
+import android.content.res.Resources
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import android.view.View
@@ -60,6 +61,7 @@
         val clockCarousel = LayoutInflater.from(context).inflate(R.layout.clock_carousel, this)
         carousel = clockCarousel.requireViewById(R.id.carousel)
         motionLayout = clockCarousel.requireViewById(R.id.motion_container)
+        motionLayout.contentDescription = context.getString(R.string.custom_clocks_label)
     }
 
     /**
@@ -69,6 +71,24 @@
         clockViewFactory = factory
     }
 
+    fun transitionToNext() {
+        val index = (carousel.currentIndex + 1) % carousel.count
+        if (index < carousel.count && index > 0) {
+            carousel.transitionToIndex(index, 0)
+        }
+    }
+
+    fun transitionToPrevious() {
+        val index = (carousel.currentIndex - 1) % carousel.count
+        if (index < carousel.count && index > 0) {
+            carousel.transitionToIndex(index, 0)
+        }
+    }
+
+    fun getContentDescription(index: Int): String {
+        return adapter.getContentDescription(index, resources)
+    }
+
     fun setUpClockCarouselView(
         clockSize: ClockSize,
         clocks: List<ClockCarouselItemViewModel>,
@@ -304,6 +324,10 @@
         private val onClockSelected: (clock: ClockCarouselItemViewModel) -> Unit
     ) : Carousel.Adapter {
 
+        fun getContentDescription(index: Int, resources: Resources): String {
+            return clocks[index].getContentDescription(resources)
+        }
+
         override fun count(): Int {
             return clocks.size
         }
@@ -336,7 +360,7 @@
             val isMiddleView = isMiddleView(viewRoot.id)
 
             // Accessibility
-            viewRoot.contentDescription = clocks[index].getContentDescription(view.resources)
+            viewRoot.contentDescription = getContentDescription(index, view.resources)
             viewRoot.isSelected = isMiddleView
 
             when (clockSize) {
diff --git a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
index 4322009..8e91798 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -46,6 +46,7 @@
 import com.android.wallpaper.module.CurrentWallpaperInfoFactory
 import com.android.wallpaper.module.CustomizationSections
 import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
+import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewClickView
 import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewSectionController
 import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewView
 import com.android.wallpaper.util.DisplayUtils
@@ -100,6 +101,8 @@
     override fun createView(context: Context): ScreenPreviewView {
         val view = super.createView(context)
         if (screen == CustomizationSections.Screen.LOCK_SCREEN) {
+            val screenPreviewClickView: ScreenPreviewClickView =
+                view.findViewById(R.id.screen_preview_click_view)
             val clockColorAndSizeButtonStub: ViewStub =
                 view.requireViewById(R.id.clock_color_and_size_button)
             clockColorAndSizeButtonStub.layoutResource = R.layout.clock_color_and_size_button
@@ -162,8 +165,10 @@
                         bindJob =
                             lifecycleOwner.lifecycleScope.launch {
                                 ClockCarouselViewBinder.bind(
+                                    context = context,
                                     carouselView = carouselView,
                                     singleClockView = singleClockView,
+                                    screenPreviewClickView = screenPreviewClickView,
                                     viewModel = viewModel,
                                     clockViewFactory = clockViewFactory,
                                     lifecycleOwner = lifecycleOwner,
diff --git a/tests/robotests/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragmentTest.kt b/tests/robotests/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragmentTest.kt
deleted file mode 100644
index 0a54312..0000000
--- a/tests/robotests/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragmentTest.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.android.customization.picker.clock.ui.fragment
-
-import android.view.View
-import androidx.appcompat.app.AppCompatActivity
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.plugins.ClockMetadata
-import com.android.systemui.plugins.ClockSettings
-import com.android.systemui.plugins.PluginManager
-import com.android.systemui.shared.clocks.ClockRegistry
-import org.junit.Assert
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
-import org.mockito.MockitoAnnotations
-import org.robolectric.Robolectric
-import org.robolectric.RobolectricTestRunner
-import org.robolectric.annotation.Config
-
-/** Tests of [ClockCustomDemoFragment]. */
-@RunWith(RobolectricTestRunner::class)
-@Config(manifest = Config.NONE)
-@Ignore("b/270606895")
-class ClockCustomDemoFragmentTest {
-    private lateinit var mActivity: AppCompatActivity
-    private var mClockCustomDemoFragment: ClockCustomDemoFragment? = null
-    @Mock private lateinit var registry: ClockRegistry
-    @Mock private lateinit var mockPluginManager: PluginManager
-
-    private var settingValue: ClockSettings? = null
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        mActivity = Robolectric.buildActivity(AppCompatActivity::class.java).get()
-        mClockCustomDemoFragment = ClockCustomDemoFragment()
-        whenever(registry.getClocks())
-            .thenReturn(
-                listOf(
-                    ClockMetadata("CLOCK_1", "Clock 1"),
-                    ClockMetadata("CLOCK_2", "Clock 2"),
-                    ClockMetadata("CLOCK_NOT_IN_USE", "Clock not in use")
-                )
-            )
-
-        mClockCustomDemoFragment!!.clockRegistry = registry
-        mClockCustomDemoFragment!!.recyclerView = RecyclerView(mActivity)
-        mClockCustomDemoFragment!!.recyclerView.layoutManager =
-            LinearLayoutManager(mActivity, RecyclerView.VERTICAL, false)
-    }
-
-    @Test
-    fun testItemCount_getCorrectClockCount() {
-        Assert.assertEquals(3, mClockCustomDemoFragment!!.recyclerView.adapter!!.itemCount)
-    }
-
-    @Test
-    fun testClick_setCorrectClockId() {
-        mClockCustomDemoFragment!!
-            .recyclerView
-            .measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
-        mClockCustomDemoFragment!!.recyclerView.layout(0, 0, 100, 10000)
-        val testPosition = 1
-        mClockCustomDemoFragment!!
-            .recyclerView
-            .findViewHolderForAdapterPosition(testPosition)
-            ?.itemView
-            ?.performClick()
-        verify(registry).currentClockId = "CLOCK_1"
-    }
-}
diff --git a/tests/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java b/tests/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java
index bcf5a5f..81890f0 100644
--- a/tests/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java
+++ b/tests/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2019 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.testing;
 
 import android.content.Context;
diff --git a/tests/src/com/android/customization/testing/TestDrawableLayerResolver.java b/tests/src/com/android/customization/testing/TestDrawableLayerResolver.java
index e507221..8b16299 100644
--- a/tests/src/com/android/customization/testing/TestDrawableLayerResolver.java
+++ b/tests/src/com/android/customization/testing/TestDrawableLayerResolver.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2019 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.testing;
 
 import android.graphics.drawable.Drawable;
diff --git a/tests/src/com/android/customization/testing/TestPackageStatusNotifier.java b/tests/src/com/android/customization/testing/TestPackageStatusNotifier.java
index 1e6a1a2..2aadae8 100644
--- a/tests/src/com/android/customization/testing/TestPackageStatusNotifier.java
+++ b/tests/src/com/android/customization/testing/TestPackageStatusNotifier.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2019 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.testing;
 
 import com.android.wallpaper.module.PackageStatusNotifier;
diff --git a/tests/src/com/android/customization/testing/TestThemeManager.java b/tests/src/com/android/customization/testing/TestThemeManager.java
index c4d25fb..5175b24 100644
--- a/tests/src/com/android/customization/testing/TestThemeManager.java
+++ b/tests/src/com/android/customization/testing/TestThemeManager.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2019 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.testing;
 
 import androidx.fragment.app.FragmentActivity;
diff --git a/tests/src/com/android/customization/testing/TestThemesUserEventLogger.java b/tests/src/com/android/customization/testing/TestThemesUserEventLogger.java
index 2bb2082..22a5b94 100644
--- a/tests/src/com/android/customization/testing/TestThemesUserEventLogger.java
+++ b/tests/src/com/android/customization/testing/TestThemesUserEventLogger.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2019 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.testing;
 
 import com.android.customization.model.color.ColorOption;