• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 
17 package com.android.launcher3.util
18 
19 import android.appwidget.AppWidgetHostView
20 import android.content.Context
21 import android.view.LayoutInflater
22 import android.view.View
23 import android.view.View.OnClickListener
24 import android.view.View.OnFocusChangeListener
25 import android.view.ViewGroup
26 import com.android.launcher3.BubbleTextView
27 import com.android.launcher3.LauncherAppState
28 import com.android.launcher3.LauncherSettings.Favorites
29 import com.android.launcher3.R
30 import com.android.launcher3.apppairs.AppPairIcon
31 import com.android.launcher3.folder.FolderIcon
32 import com.android.launcher3.model.ModelWriter
33 import com.android.launcher3.model.data.AppPairInfo
34 import com.android.launcher3.model.data.FolderInfo
35 import com.android.launcher3.model.data.ItemInfo
36 import com.android.launcher3.model.data.LauncherAppWidgetInfo
37 import com.android.launcher3.model.data.WorkspaceItemFactory
38 import com.android.launcher3.model.data.WorkspaceItemInfo
39 import com.android.launcher3.views.ActivityContext
40 import com.android.launcher3.widget.LauncherWidgetHolder
41 import com.android.launcher3.widget.PendingAppWidgetHostView
42 import com.android.launcher3.widget.WidgetInflater
43 
44 /** Utility class to inflate View for a model item */
45 class ItemInflater<T>(
46     private val context: T,
47     private val widgetHolder: LauncherWidgetHolder,
48     private val clickListener: OnClickListener,
49     private val focusListener: OnFocusChangeListener,
50     private val defaultParent: ViewGroup,
51 ) where T : Context, T : ActivityContext {
52 
53     private val widgetInflater =
54         WidgetInflater(context, LauncherAppState.getInstance(context).isSafeModeEnabled)
55 
56     @JvmOverloads
inflateItemnull57     fun inflateItem(item: ItemInfo, writer: ModelWriter, nullableParent: ViewGroup? = null): View? {
58         val parent = nullableParent ?: defaultParent
59         when (item.itemType) {
60             Favorites.ITEM_TYPE_APPLICATION,
61             Favorites.ITEM_TYPE_DEEP_SHORTCUT,
62             Favorites.ITEM_TYPE_SEARCH_ACTION -> {
63                 var info =
64                     if (item is WorkspaceItemFactory) {
65                         (item as WorkspaceItemFactory).makeWorkspaceItem(context)
66                     } else {
67                         item as WorkspaceItemInfo
68                     }
69                 if (info.container == Favorites.CONTAINER_PREDICTION) {
70                     // Came from all apps prediction row -- make a copy
71                     info = WorkspaceItemInfo(info)
72                 }
73                 return createShortcut(info, parent)
74             }
75             Favorites.ITEM_TYPE_FOLDER ->
76                 return FolderIcon.inflateFolderAndIcon(
77                     R.layout.folder_icon,
78                     context,
79                     parent,
80                     item as FolderInfo,
81                 )
82             Favorites.ITEM_TYPE_APP_PAIR ->
83                 return AppPairIcon.inflateIcon(
84                     R.layout.app_pair_icon,
85                     context,
86                     parent,
87                     item as AppPairInfo,
88                     BubbleTextView.DISPLAY_WORKSPACE,
89                 )
90             Favorites.ITEM_TYPE_APPWIDGET,
91             Favorites.ITEM_TYPE_CUSTOM_APPWIDGET ->
92                 return inflateAppWidget(item as LauncherAppWidgetInfo, writer)
93             else -> throw RuntimeException("Invalid Item Type")
94         }
95     }
96 
97     /**
98      * Creates a view representing a shortcut inflated from the specified resource.
99      *
100      * @param parent The group the shortcut belongs to. This is not necessarily the group where the
101      *   shortcut should be added.
102      * @param info The data structure describing the shortcut.
103      * @return A View inflated from layoutResId.
104      */
createShortcutnull105     private fun createShortcut(info: WorkspaceItemInfo, parent: ViewGroup): View {
106         val favorite =
107             LayoutInflater.from(parent.context).inflate(R.layout.app_icon, parent, false)
108                 as BubbleTextView
109         favorite.applyFromWorkspaceItem(info)
110         favorite.setOnClickListener(clickListener)
111         favorite.onFocusChangeListener = focusListener
112         return favorite
113     }
114 
inflateAppWidgetnull115     private fun inflateAppWidget(item: LauncherAppWidgetInfo, writer: ModelWriter): View? {
116         TraceHelper.INSTANCE.beginSection("BIND_WIDGET_id=" + item.appWidgetId)
117         try {
118             val (type, reason, _, isUpdate, widgetInfo) = widgetInflater.inflateAppWidget(item)
119             if (type == WidgetInflater.TYPE_DELETE) {
120                 writer.deleteItemFromDatabase(item, reason)
121                 return null
122             }
123             if (isUpdate) {
124                 writer.updateItemInDatabase(item)
125             }
126             val view =
127                 if (type == WidgetInflater.TYPE_PENDING || widgetInfo == null)
128                     PendingAppWidgetHostView(context, widgetHolder, item, widgetInfo)
129                 else widgetHolder.createView(item.appWidgetId, widgetInfo)
130             prepareAppWidget(view, item)
131             return view
132         } finally {
133             TraceHelper.INSTANCE.endSection()
134         }
135     }
136 
prepareAppWidgetnull137     fun prepareAppWidget(hostView: AppWidgetHostView, item: LauncherAppWidgetInfo) {
138         hostView.tag = item
139         hostView.isFocusable = true
140         hostView.onFocusChangeListener = focusListener
141     }
142 }
143