1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.permissioncontroller.permission.ui.auto
17 
18 import android.app.Application
19 import android.content.Context
20 import android.os.Bundle
21 import android.os.UserHandle
22 import androidx.preference.Preference
23 import androidx.preference.PreferenceCategory
24 import com.android.permissioncontroller.R
25 import com.android.permissioncontroller.auto.AutoSettingsFrameFragment
26 import com.android.permissioncontroller.hibernation.isHibernationEnabled
27 import com.android.permissioncontroller.permission.ui.UnusedAppsFragment
28 import com.android.permissioncontroller.permission.ui.UnusedAppsFragment.Companion.INFO_MSG_CATEGORY
29 import com.android.car.ui.utils.ViewUtils
30 import com.android.car.ui.utils.ViewUtils.LazyLayoutView
31 
32 /**
33  * Auto wrapper, with customizations, around [UnusedAppsFragment].
34  */
35 class AutoUnusedAppsFragment : AutoSettingsFrameFragment(),
36     UnusedAppsFragment.Parent<AutoUnusedAppsPreference> {
37 
38     companion object {
39         private const val UNUSED_PREFERENCE_KEY = "unused_pref_row_key"
40 
41         /** Create a new instance of this fragment.  */
42         @JvmStatic
43         fun newInstance(): AutoUnusedAppsFragment {
44             return AutoUnusedAppsFragment()
45         }
46     }
47 
48     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
49         // Preferences will be added via shared logic in [UnusedAppsFragment].
50     }
51 
52     override fun onActivityCreated(savedInstanceState: Bundle?) {
53         super.onActivityCreated(savedInstanceState)
54         if (savedInstanceState == null) {
55             val fragment:
56                 UnusedAppsFragment<AutoUnusedAppsFragment, AutoUnusedAppsPreference> =
57                 UnusedAppsFragment.newInstance()
58             fragment.arguments = arguments
59             // child fragment does not have its own UI - it will add to the preferences of this
60             // parent fragment
61             childFragmentManager.beginTransaction()
62                 .add(fragment, null)
63                 .commit()
64         }
65 
66         // initially focus on focus parking view and then shift focus to recyclerview once it has
67         // loaded
68         ViewUtils.hideFocus(getCarUiRecyclerView().getView().getRootView())
69         val lazyLayoutView = getCarUiRecyclerView() as LazyLayoutView
70         ViewUtils.initFocus(lazyLayoutView)
71     }
72 
73     override fun createFooterPreference(context: Context): Preference {
74         val preference = Preference(context)
75         if (isHibernationEnabled()) {
76             preference.summary = getString(R.string.unused_apps_page_summary)
77         } else {
78             preference.summary = """
79             ${getString(R.string.auto_revoked_apps_page_summary)}
80             ${getString(R.string.auto_revoke_open_app_message)}
81             """.trimIndent()
82         }
83         preference.setIcon(R.drawable.ic_info_outline)
84         preference.isSelectable = false
85         return preference
86     }
87 
88     override fun setLoadingState(loading: Boolean, animate: Boolean) {
89         setLoading(false)
90     }
91 
92     override fun createUnusedAppPref(
93         app: Application,
94         packageName: String,
95         user: UserHandle,
96         context: Context
97     ): AutoUnusedAppsPreference {
98         return AutoUnusedAppsPreference(app, packageName, user, context)
99     }
100 
101     override fun setTitle(title: CharSequence) {
102         headerLabel = title
103     }
104 
105     override fun setEmptyState(empty: Boolean) {
106         val infoMsgCategory =
107                 preferenceScreen.findPreference<PreferenceCategory>(INFO_MSG_CATEGORY)!!
108         val noUnusedAppsPreference: Preference? =
109                 infoMsgCategory.findPreference<Preference>(UNUSED_PREFERENCE_KEY)
110         if (empty && noUnusedAppsPreference == null) {
111             infoMsgCategory.addPreference(createNoUnusedAppsPreference())
112         } else if (noUnusedAppsPreference != null) {
113             noUnusedAppsPreference.setVisible(empty)
114         }
115     }
116 
117     private fun createNoUnusedAppsPreference(): Preference {
118         val preference = Preference(context)
119         preference.title = getString(R.string.zero_unused_apps)
120         preference.key = UNUSED_PREFERENCE_KEY
121         preference.isSelectable = false
122         preference.order = 0
123         return preference
124     }
125 }