1 /* <lambda>null2 * 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.model.data 18 19 import android.content.Context 20 import com.android.launcher3.LauncherSettings 21 import com.android.launcher3.LauncherSettings.Favorites.DESKTOP_ICON_FLAG 22 import com.android.launcher3.R 23 import com.android.launcher3.icons.IconCache 24 import com.android.launcher3.logger.LauncherAtom 25 import com.android.launcher3.views.ActivityContext 26 import java.util.stream.Collectors 27 28 /** A type of app collection that launches multiple apps into split screen. */ 29 class AppPairInfo() : CollectionInfo() { 30 private var contents: ArrayList<WorkspaceItemInfo> = ArrayList() 31 32 init { 33 itemType = LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR 34 } 35 36 /** Convenience constructor, calls primary constructor and init block */ 37 constructor(apps: List<WorkspaceItemInfo>) : this() { 38 apps.forEach(this::add) 39 } 40 41 /** Creates a new AppPairInfo that is a copy of the provided one. */ 42 constructor(appPairInfo: AppPairInfo) : this() { 43 contents = appPairInfo.contents.clone() as ArrayList<WorkspaceItemInfo> 44 copyFrom(appPairInfo) 45 } 46 47 /** Adds an element to the contents ArrayList. */ 48 override fun add(item: ItemInfo) { 49 if (item !is WorkspaceItemInfo) { 50 throw RuntimeException("tried to add an illegal type into an app pair") 51 } 52 53 contents.add(item) 54 } 55 56 /** Returns the app pair's member apps as an ArrayList of [ItemInfo]. */ 57 override fun getContents(): ArrayList<ItemInfo> = 58 ArrayList(contents.stream().map { it as ItemInfo }.collect(Collectors.toList())) 59 60 /** Returns the app pair's member apps as an ArrayList of [WorkspaceItemInfo]. */ 61 override fun getAppContents(): ArrayList<WorkspaceItemInfo> = contents 62 63 /** Returns the first app in the pair. */ 64 fun getFirstApp() = contents[0] 65 66 /** Returns the second app in the pair. */ 67 fun getSecondApp() = contents[1] 68 69 /** Returns if either of the app pair members is currently disabled. */ 70 override fun isDisabled() = anyMatch { it.isDisabled } 71 72 /** Checks if member apps are launchable at the current screen size. */ 73 fun isLaunchable(context: Context): Pair<Boolean, Boolean> { 74 val isTablet = 75 (ActivityContext.lookupContext(context) as ActivityContext).getDeviceProfile().isTablet 76 return Pair( 77 isTablet || !getFirstApp().isNonResizeable, 78 isTablet || !getSecondApp().isNonResizeable, 79 ) 80 } 81 82 /** Fetches high-res icons for member apps if needed. */ 83 fun fetchHiResIconsIfNeeded(iconCache: IconCache) { 84 getAppContents() 85 .stream() 86 .filter { it.matchingLookupFlag.isVisuallyLessThan(DESKTOP_ICON_FLAG) } 87 .forEach { member -> iconCache.getTitleAndIcon(member, DESKTOP_ICON_FLAG) } 88 } 89 90 /** 91 * App pairs will report itself as "disabled" (for accessibility) if either of the following is 92 * true: 93 * 1) One of the member WorkspaceItemInfos is disabled (i.e. the app software itself is paused 94 * or can't be launched for some other reason). 95 * 2) One of the member apps can't be launched due to screen size requirements. 96 */ 97 fun shouldReportDisabled(context: Context): Boolean { 98 return isDisabled || !isLaunchable(context).first || !isLaunchable(context).second 99 } 100 101 /** Generates a default title for the app pair and sets it. */ 102 fun generateTitle(context: Context): CharSequence? { 103 val app1: CharSequence? = getFirstApp().title 104 val app2: CharSequence? = getSecondApp().title 105 title = context.getString(R.string.app_pair_default_title, app1, app2) 106 return title 107 } 108 109 /** Generates an ItemInfo for logging. */ 110 override fun buildProto(cInfo: CollectionInfo?, context: Context): LauncherAtom.ItemInfo { 111 val appPairIcon = LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size) 112 appPairIcon.setLabelInfo(title.toString()) 113 return getDefaultItemInfoBuilder(context) 114 .setFolderIcon(appPairIcon) 115 .setRank(rank) 116 .setContainerInfo(getContainerInfo()) 117 .build() 118 } 119 } 120