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