Cherish: Import BasePreferenceController and DashboardFragment from Krypton
Signed-off-by: Hưng Phan <phandinhhungvp2001@gmail.com>
This commit is contained in:
65
res/layout/app_list_item.xml
Normal file
65
res/layout/app_list_item.xml
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 AOSP-Krypton 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.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<androidx.preference.internal.PreferenceImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:scaleType="centerInside"
|
||||
settings:layout_constraintStart_toStartOf="parent"
|
||||
settings:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/default_margin"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
settings:layout_constraintStart_toEndOf="@id/icon"
|
||||
settings:layout_constraintEnd_toStartOf="@id/checkBox"
|
||||
settings:layout_constraintTop_toTopOf="@id/icon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/packageName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
settings:layout_constraintStart_toStartOf="@id/label"
|
||||
settings:layout_constraintEnd_toEndOf="@id/label"
|
||||
settings:layout_constraintTop_toBottomOf="@id/label"
|
||||
settings:layout_constraintBottom_toBottomOf="@id/icon" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkBox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusable="false"
|
||||
android:clickable="false"
|
||||
settings:layout_constraintBottom_toBottomOf="@id/icon"
|
||||
settings:layout_constraintEnd_toEndOf="parent"
|
||||
settings:layout_constraintTop_toTopOf="@id/icon" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
27
res/layout/app_list_layout.xml
Normal file
27
res/layout/app_list_layout.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021-2022 AOSP-Krypton 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.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/apps_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
</FrameLayout>
|
||||
21
res/menu/app_list_menu.xml
Normal file
21
res/menu/app_list_menu.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 AOSP-Krypton 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.
|
||||
-->
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/search"
|
||||
android:title="@string/search"
|
||||
android:icon="@drawable/ic_find_in_page_24px"
|
||||
android:showAsAction="ifRoom|collapseActionView"
|
||||
android:actionViewClass="android.widget.SearchView" />
|
||||
</menu>
|
||||
@@ -30,4 +30,7 @@
|
||||
<dimen name="fod_picker_item_margin">10dp</dimen>
|
||||
<dimen name="fod_picker_item_size">100dp</dimen>
|
||||
<dimen name="fod_picker_item_padding">20dp</dimen>
|
||||
|
||||
<dimen name="default_margin">16dp</dimen>
|
||||
<dimen name="default_padding">16dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -710,4 +710,6 @@
|
||||
<string name="use_stream_spoof_summary">Enable Higher quality streams on Amazon Prime, Disney+, Hotstar, and Netflix. (Mileage will vary per-device)</string>
|
||||
<string name="stream_spoof_toast">Restart the streaming app for it to take effect</string>
|
||||
|
||||
<string name="search">Search</string>
|
||||
<string name="search_apps">Search apps</string>
|
||||
</resources>
|
||||
|
||||
70
src/com/cherish/settings/CherishBasePreferenceController.kt
Normal file
70
src/com/cherish/settings/CherishBasePreferenceController.kt
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2022 AOSP-Krypton 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.cherish.settings
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
|
||||
import com.android.settings.core.BasePreferenceController
|
||||
import com.android.settings.core.PreferenceControllerMixin
|
||||
import com.android.settingslib.search.SearchIndexableRaw
|
||||
|
||||
abstract class CherishBasePreferenceController(
|
||||
private val context: Context,
|
||||
private val key: String,
|
||||
): BasePreferenceController(context, key),
|
||||
PreferenceControllerMixin {
|
||||
|
||||
/**
|
||||
* Updates non-indexable keys for search provider.
|
||||
*
|
||||
* Called by SearchIndexProvider#getNonIndexableKeys
|
||||
*/
|
||||
override fun updateNonIndexableKeys(keys: MutableList<String>) {
|
||||
val shouldSuppressFromSearch = !isAvailable()
|
||||
|| getAvailabilityStatus() == AVAILABLE_UNSEARCHABLE
|
||||
if (shouldSuppressFromSearch) {
|
||||
if (preferenceKey?.isBlank() == true) {
|
||||
Log.w(TAG, "Skipping updateNonIndexableKeys due to empty key " + toString())
|
||||
return
|
||||
}
|
||||
if (keys.contains(key)) {
|
||||
Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list. " + toString())
|
||||
return
|
||||
}
|
||||
keys.add(key)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates raw data for search provider.
|
||||
*
|
||||
* Called by SearchIndexProvider#getRawDataToIndex
|
||||
*/
|
||||
override open fun updateRawDataToIndex(rawData: MutableList<SearchIndexableRaw>) {}
|
||||
|
||||
/**
|
||||
* Updates dynamic raw data for search provider.
|
||||
*
|
||||
* Called by SearchIndexProvider#getDynamicRawDataToIndex
|
||||
*/
|
||||
override open fun updateDynamicRawDataToIndex(rawData: MutableList<SearchIndexableRaw>) {}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "CherishBasePreferenceController"
|
||||
}
|
||||
}
|
||||
317
src/com/cherish/settings/fragments/AppListFragment.kt
Normal file
317
src/com/cherish/settings/fragments/AppListFragment.kt
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 AOSP-Krypton 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.cherish.settings.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CheckBox
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.SearchView
|
||||
import android.widget.TextView
|
||||
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
import com.android.settings.R
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
* [Fragment] that hosts a [RecyclerView] with a vertical
|
||||
* list of application info. Items display an icon, name
|
||||
* and package name of the application, along with a [CheckBox]
|
||||
* indicating whether the item is selected or not.
|
||||
*/
|
||||
abstract class AppListFragment: Fragment(R.layout.app_list_layout), MenuItem.OnActionExpandListener {
|
||||
|
||||
private val mutex = Mutex()
|
||||
|
||||
private lateinit var fragmentScope: CoroutineScope
|
||||
private lateinit var progressBar: ProgressBar
|
||||
private lateinit var appBarLayout: AppBarLayout
|
||||
private lateinit var packageManager: PackageManager
|
||||
private lateinit var recyclerView: RecyclerView
|
||||
private lateinit var adapter: AppListAdapter
|
||||
|
||||
private val packageList = mutableListOf<PackageInfo>()
|
||||
|
||||
private var searchText = ""
|
||||
private var displayCategory: Int = CATEGORY_USER_ONLY
|
||||
private var packageFilter: ((PackageInfo) -> Boolean) = { true }
|
||||
private var packageComparator: ((PackageInfo, PackageInfo) -> Int) = { a, b ->
|
||||
getLabel(a).compareTo(getLabel(b))
|
||||
}
|
||||
|
||||
private var needsToHideProgressBar = false
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
fragmentScope = CoroutineScope(Dispatchers.Main)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
packageManager = requireContext().packageManager
|
||||
packageList.addAll(packageManager.getInstalledPackages(0))
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this function to set the title of this fragment.
|
||||
*/
|
||||
abstract protected fun getTitle(): Int
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
requireActivity().setTitle(getTitle())
|
||||
appBarLayout = requireActivity().findViewById(R.id.app_bar)
|
||||
progressBar = view.findViewById(R.id.loading_progress)
|
||||
adapter = AppListAdapter()
|
||||
recyclerView = view.findViewById<RecyclerView>(R.id.apps_list).also {
|
||||
it.layoutManager = LinearLayoutManager(context)
|
||||
it.adapter = adapter
|
||||
}
|
||||
needsToHideProgressBar = true
|
||||
refreshList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract function for subclasses to override for providing
|
||||
* an inital list of packages that should appear as selected.
|
||||
*/
|
||||
abstract protected fun getInitialCheckedList(): List<String>
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.app_list_menu, menu)
|
||||
val searchItem = menu.findItem(R.id.search).also {
|
||||
it.setOnActionExpandListener(this)
|
||||
}
|
||||
val searchView = searchItem.actionView as SearchView
|
||||
searchView.setQueryHint(getString(R.string.search_apps));
|
||||
searchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String) = false
|
||||
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
fragmentScope.launch {
|
||||
mutex.withLock {
|
||||
searchText = newText
|
||||
}
|
||||
refreshList()
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||
// To prevent a large space on tool bar.
|
||||
appBarLayout.setExpanded(false /*expanded*/, false /*animate*/)
|
||||
// To prevent user expanding the collapsing tool bar view.
|
||||
ViewCompat.setNestedScrollingEnabled(recyclerView, false)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
|
||||
// We keep the collapsed status after user cancel the search function.
|
||||
appBarLayout.setExpanded(false /*expanded*/, false /*animate*/)
|
||||
// Allow user to expande the tool bar view.
|
||||
ViewCompat.setNestedScrollingEnabled(recyclerView, true)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDetach() {
|
||||
fragmentScope.cancel()
|
||||
super.onDetach()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of apps that should be displayed in the list.
|
||||
* Defaults to [CATEGORY_USER_ONLY].
|
||||
*
|
||||
* @param category one of [CATEGORY_SYSTEM_ONLY],
|
||||
* [CATEGORY_USER_ONLY], [CATEGORY_BOTH]
|
||||
*/
|
||||
fun setDisplayCategory(category: Int) {
|
||||
fragmentScope.launch {
|
||||
mutex.withLock {
|
||||
displayCategory = category
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom filter to filter out items from the list.
|
||||
*
|
||||
* @param customFilter a function that takes a [PackageInfo] and
|
||||
* returns a [Boolean] indicating whether to show the item or not.
|
||||
*/
|
||||
fun setCustomFilter(customFilter: ((packageInfo: PackageInfo) -> Boolean)) {
|
||||
fragmentScope.launch {
|
||||
mutex.withLock {
|
||||
packageFilter = customFilter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a [Comparator] for sorting the elements in the list..
|
||||
*
|
||||
* @param comparator a function that takes two [PackageInfo]'s and returns
|
||||
* an [Int] representing their relative priority.
|
||||
*/
|
||||
fun setComparator(comparator: ((a: PackageInfo, b: PackageInfo) -> Int)) {
|
||||
fragmentScope.launch {
|
||||
mutex.withLock {
|
||||
packageComparator = comparator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when user selected list is updated.
|
||||
*
|
||||
* @param list a [List<String>] of selected items.
|
||||
*/
|
||||
open protected fun onListUpdate(list: List<String>) {}
|
||||
|
||||
/**
|
||||
* Called when user selected an application.
|
||||
*
|
||||
* @param packageName the package name of the selected app.
|
||||
*/
|
||||
open protected fun onAppSelected(packageName: String) {}
|
||||
|
||||
/**
|
||||
* Called when user deselected an application.
|
||||
*
|
||||
* @param packageName the package name of the deselected app.
|
||||
*/
|
||||
open protected fun onAppDeselected(packageName: String) {}
|
||||
|
||||
protected fun refreshList() {
|
||||
fragmentScope.launch {
|
||||
val list = withContext(Dispatchers.Default) {
|
||||
mutex.withLock {
|
||||
packageList.filter {
|
||||
when (displayCategory) {
|
||||
CATEGORY_SYSTEM_ONLY -> it.applicationInfo.isSystemApp()
|
||||
CATEGORY_USER_ONLY -> !it.applicationInfo.isSystemApp()
|
||||
else -> true
|
||||
} &&
|
||||
getLabel(it).contains(searchText, true) &&
|
||||
packageFilter(it)
|
||||
}.sortedWith(packageComparator).map { appInfofromPackage(it) }
|
||||
}
|
||||
}
|
||||
adapter.submitList(list)
|
||||
if (needsToHideProgressBar) {
|
||||
progressBar.visibility = View.GONE
|
||||
needsToHideProgressBar = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun appInfofromPackage(packageInfo: PackageInfo): AppInfo =
|
||||
AppInfo(
|
||||
packageInfo.packageName,
|
||||
getLabel(packageInfo),
|
||||
packageInfo.applicationInfo.loadIcon(packageManager),
|
||||
)
|
||||
|
||||
private fun getLabel(packageInfo: PackageInfo) =
|
||||
packageInfo.applicationInfo.loadLabel(packageManager).toString()
|
||||
|
||||
private inner class AppListAdapter :
|
||||
ListAdapter<AppInfo, AppListViewHolder>(itemCallback)
|
||||
{
|
||||
private val checkedList = getInitialCheckedList().toMutableList()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
AppListViewHolder(layoutInflater.inflate(
|
||||
R.layout.app_list_item, parent, false))
|
||||
|
||||
override fun onBindViewHolder(holder: AppListViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
val pkg = item.packageName
|
||||
holder.label.setText(item.label)
|
||||
holder.packageName.setText(pkg)
|
||||
holder.icon.setImageDrawable(item.icon)
|
||||
holder.checkBox.setChecked(checkedList.contains(pkg))
|
||||
holder.itemView.setOnClickListener {
|
||||
if (checkedList.contains(pkg)){
|
||||
checkedList.remove(pkg)
|
||||
onAppDeselected(pkg)
|
||||
} else {
|
||||
checkedList.add(pkg)
|
||||
onAppSelected(pkg)
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
onListUpdate(checkedList.toList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class AppListViewHolder(itemView: View) :
|
||||
RecyclerView.ViewHolder(itemView) {
|
||||
val icon: ImageView = itemView.findViewById(R.id.icon)
|
||||
val label: TextView = itemView.findViewById(R.id.label)
|
||||
val packageName: TextView = itemView.findViewById(R.id.packageName)
|
||||
val checkBox: CheckBox = itemView.findViewById(R.id.checkBox)
|
||||
}
|
||||
|
||||
private data class AppInfo(
|
||||
val packageName: String,
|
||||
val label: String,
|
||||
val icon: Drawable,
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val TAG = "AppListFragment"
|
||||
|
||||
const val CATEGORY_SYSTEM_ONLY = 0
|
||||
const val CATEGORY_USER_ONLY = 1
|
||||
const val CATEGORY_BOTH = 2
|
||||
|
||||
private val itemCallback = object : DiffUtil.ItemCallback<AppInfo>() {
|
||||
override fun areItemsTheSame(oldInfo: AppInfo, newInfo: AppInfo) =
|
||||
oldInfo.packageName == newInfo.packageName
|
||||
|
||||
override fun areContentsTheSame(oldInfo: AppInfo, newInfo: AppInfo) =
|
||||
oldInfo == newInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2021 AOSP-Krypton 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.cherish.settings.fragment
|
||||
|
||||
import androidx.preference.Preference
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto
|
||||
import com.android.settings.dashboard.DashboardFragment
|
||||
|
||||
abstract class CherishDashboardFragment: DashboardFragment() {
|
||||
override fun getMetricsCategory(): Int = MetricsProto.MetricsEvent.CHERISH_SETTINGS
|
||||
|
||||
override fun onDisplayPreferenceDialog(preference: Preference) {
|
||||
super.onDisplayPreferenceDialog(preference)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val REQUEST_KEY = "CherishDashboardFragment#RequestKey"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user