1 /* 2 * Copyright (C) 2018 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.launcher3.views; 17 18 import android.content.Context; 19 import android.content.ContextWrapper; 20 import android.graphics.Rect; 21 import android.view.LayoutInflater; 22 import android.view.View; 23 import android.view.View.AccessibilityDelegate; 24 25 import androidx.annotation.Nullable; 26 27 import com.android.launcher3.DeviceProfile; 28 import com.android.launcher3.dot.DotInfo; 29 import com.android.launcher3.dragndrop.DragController; 30 import com.android.launcher3.folder.FolderIcon; 31 import com.android.launcher3.logger.LauncherAtom; 32 import com.android.launcher3.logging.StatsLogManager; 33 import com.android.launcher3.model.data.ItemInfo; 34 import com.android.launcher3.util.ViewCache; 35 36 /** 37 * An interface to be used along with a context for various activities in Launcher. This allows a 38 * generic class to depend on Context subclass instead of an Activity. 39 */ 40 public interface ActivityContext { 41 finishAutoCancelActionMode()42 default boolean finishAutoCancelActionMode() { 43 return false; 44 } 45 getDotInfoForItem(ItemInfo info)46 default DotInfo getDotInfoForItem(ItemInfo info) { 47 return null; 48 } 49 50 /** 51 * For items with tree hierarchy, notifies the activity to invalidate the parent when a root 52 * is invalidated 53 * @param info info associated with a root node. 54 */ invalidateParent(ItemInfo info)55 default void invalidateParent(ItemInfo info) { } 56 getAccessibilityDelegate()57 default AccessibilityDelegate getAccessibilityDelegate() { 58 return null; 59 } 60 getFolderBoundingBox()61 default Rect getFolderBoundingBox() { 62 return getDeviceProfile().getAbsoluteOpenFolderBounds(); 63 } 64 65 /** 66 * After calling {@link #getFolderBoundingBox()}, we calculate a (left, top) position for a 67 * Folder of size width x height to be within those bounds. However, the chosen position may 68 * not be visually ideal (e.g. uncanny valley of centeredness), so here's a chance to update it. 69 * @param inOutPosition A 2-size array where the first element is the left position of the open 70 * folder and the second element is the top position. Should be updated in place if desired. 71 * @param bounds The bounds that the open folder should fit inside. 72 * @param width The width of the open folder. 73 * @param height The height of the open folder. 74 */ updateOpenFolderPosition(int[] inOutPosition, Rect bounds, int width, int height)75 default void updateOpenFolderPosition(int[] inOutPosition, Rect bounds, int width, int height) { 76 } 77 78 /** 79 * Returns a LayoutInflater that is cloned in this Context, so that Views inflated by it will 80 * have the same Context. (i.e. {@link #lookupContext(Context)} will find this ActivityContext.) 81 */ getLayoutInflater()82 default LayoutInflater getLayoutInflater() { 83 if (this instanceof Context) { 84 Context context = (Context) this; 85 return LayoutInflater.from(context).cloneInContext(context); 86 } 87 return null; 88 } 89 90 /** 91 * The root view to support drag-and-drop and popup support. 92 */ getDragLayer()93 BaseDragLayer getDragLayer(); 94 getDeviceProfile()95 DeviceProfile getDeviceProfile(); 96 getViewCache()97 default ViewCache getViewCache() { 98 return new ViewCache(); 99 } 100 101 /** 102 * Controller for supporting item drag-and-drop 103 */ getDragController()104 default <T extends DragController> T getDragController() { 105 return null; 106 } 107 108 /** 109 * Returns the FolderIcon with the given item id, if it exists. 110 */ findFolderIcon(final int folderIconId)111 default @Nullable FolderIcon findFolderIcon(final int folderIconId) { 112 return null; 113 } 114 getStatsLogManager()115 default StatsLogManager getStatsLogManager() { 116 return StatsLogManager.newInstance((Context) this); 117 } 118 119 /** 120 * Returns {@code true} if popups should use color extraction. 121 */ shouldUseColorExtractionForPopup()122 default boolean shouldUseColorExtractionForPopup() { 123 return true; 124 } 125 126 /** 127 * Returns whether we can show the IME for elements hosted by this ActivityContext. 128 */ supportsIme()129 default boolean supportsIme() { 130 return true; 131 } 132 133 /** 134 * Called just before logging the given item. 135 */ applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder)136 default void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) { } 137 138 /** 139 * Returns the ActivityContext associated with the given Context, or throws an exception if 140 * the Context is not associated with any ActivityContext. 141 */ lookupContext(Context context)142 static <T extends Context & ActivityContext> T lookupContext(Context context) { 143 T activityContext = lookupContextNoThrow(context); 144 if (activityContext == null) { 145 throw new IllegalArgumentException("Cannot find ActivityContext in parent tree"); 146 } 147 return activityContext; 148 } 149 150 /** 151 * Returns the ActivityContext associated with the given Context, or null if 152 * the Context is not associated with any ActivityContext. 153 */ lookupContextNoThrow(Context context)154 static <T extends Context & ActivityContext> T lookupContextNoThrow(Context context) { 155 if (context instanceof ActivityContext) { 156 return (T) context; 157 } else if (context instanceof ContextWrapper) { 158 return lookupContextNoThrow(((ContextWrapper) context).getBaseContext()); 159 } else { 160 return null; 161 } 162 } 163 getItemOnClickListener()164 default View.OnClickListener getItemOnClickListener() { 165 return v -> { 166 // No op. 167 }; 168 } 169 } 170