1 /* 2 * Copyright (C) 2008 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; 18 19 import android.database.sqlite.SQLiteDatabase; 20 import android.provider.BaseColumns; 21 22 import androidx.annotation.NonNull; 23 24 import com.android.launcher3.model.data.ItemInfo; 25 26 import java.util.LinkedHashMap; 27 import java.util.stream.Collectors; 28 29 /** 30 * Settings related utilities. 31 */ 32 public class LauncherSettings { 33 34 /** 35 * Types of animations. 36 */ 37 public static final class Animation { 38 /** 39 * The default animation for a given view/item info type. 40 */ 41 public static final int DEFAULT = 0; 42 /** 43 * An animation using the view's background. 44 */ 45 public static final int VIEW_BACKGROUND = 1; 46 /** 47 * The default animation for a given view/item info type, but without the splash icon. 48 */ 49 public static final int DEFAULT_NO_ICON = 2; 50 } 51 52 /** 53 * Favorites. 54 */ 55 public static final class Favorites implements BaseColumns { 56 /** 57 * The time of the last update to this row. 58 * <P>Type: INTEGER</P> 59 */ 60 public static final String MODIFIED = "modified"; 61 62 /** 63 * Descriptive name of the gesture that can be displayed to the user. 64 * <P>Type: TEXT</P> 65 */ 66 public static final String TITLE = "title"; 67 68 /** 69 * The Intent URL of the gesture, describing what it points to. This 70 * value is given to {@link android.content.Intent#parseUri(String, int)} to create 71 * an Intent that can be launched. 72 * <P>Type: TEXT</P> 73 */ 74 public static final String INTENT = "intent"; 75 76 /** 77 * The type of the gesture 78 * 79 * <P>Type: INTEGER</P> 80 */ 81 public static final String ITEM_TYPE = "itemType"; 82 83 /** 84 * The gesture is a package 85 */ 86 public static final int ITEM_TYPE_NON_ACTIONABLE = -1; 87 /** 88 * The gesture is an application 89 */ 90 public static final int ITEM_TYPE_APPLICATION = 0; 91 92 /** 93 * The gesture is an application created shortcut 94 * @deprecated This is no longer supported. Use {@link #ITEM_TYPE_DEEP_SHORTCUT} instead 95 */ 96 @Deprecated 97 public static final int ITEM_TYPE_SHORTCUT = 1; 98 99 /** 100 * The favorite is a user created folder 101 */ 102 public static final int ITEM_TYPE_FOLDER = 2; 103 104 /** 105 * The favorite is a widget 106 */ 107 public static final int ITEM_TYPE_APPWIDGET = 4; 108 109 /** 110 * The favorite is a custom widget provided by the launcher 111 */ 112 public static final int ITEM_TYPE_CUSTOM_APPWIDGET = 5; 113 114 /** 115 * The gesture is an application created deep shortcut 116 */ 117 public static final int ITEM_TYPE_DEEP_SHORTCUT = 6; 118 119 /** 120 * The favorite is an app pair for launching split screen 121 */ 122 public static final int ITEM_TYPE_APP_PAIR = 10; 123 124 // *** Below enum values are used for metrics purpose but not used in Favorites DB *** 125 126 /** 127 * Type of the item is recents task. 128 */ 129 public static final int ITEM_TYPE_TASK = 7; 130 131 /** 132 * The item is QSB 133 */ 134 public static final int ITEM_TYPE_QSB = 8; 135 136 /** 137 * The favorite is a search action 138 */ 139 public static final int ITEM_TYPE_SEARCH_ACTION = 9; 140 141 /** 142 * Private space install app button. 143 */ 144 public static final int ITEM_TYPE_PRIVATE_SPACE_INSTALL_APP_BUTTON = 11; 145 146 /** 147 * The custom icon bitmap. 148 * <P>Type: BLOB</P> 149 */ 150 public static final String ICON = "icon"; 151 152 public static final String TABLE_NAME = "favorites"; 153 154 /** 155 * Backup table created when user hotseat is moved to workspace for hybrid hotseat 156 */ 157 public static final String HYBRID_HOTSEAT_BACKUP_TABLE = "hotseat_restore_backup"; 158 159 /** 160 * Temporary table used specifically for multi-db grid migrations 161 */ 162 public static final String TMP_TABLE = "favorites_tmp"; 163 164 /** 165 * The container holding the favorite 166 * <P>Type: INTEGER</P> 167 */ 168 public static final String CONTAINER = "container"; 169 170 /** 171 * The icon is a resource identified by a package name and an integer id. 172 */ 173 public static final int CONTAINER_DESKTOP = -100; 174 public static final int CONTAINER_HOTSEAT = -101; 175 public static final int CONTAINER_PREDICTION = -102; 176 public static final int CONTAINER_WIDGETS_PREDICTION = -111; 177 public static final int CONTAINER_HOTSEAT_PREDICTION = -103; 178 public static final int CONTAINER_ALL_APPS = -104; 179 public static final int CONTAINER_WIDGETS_TRAY = -105; 180 public static final int CONTAINER_BOTTOM_WIDGETS_TRAY = -112; 181 public static final int CONTAINER_PIN_WIDGETS = -113; 182 public static final int CONTAINER_WALLPAPERS = -114; 183 public static final int CONTAINER_SHORTCUTS = -107; 184 public static final int CONTAINER_SETTINGS = -108; 185 public static final int CONTAINER_TASKSWITCHER = -109; 186 public static final int CONTAINER_PRIVATESPACE = -110; 187 188 // Represents any of the extended containers implemented in non-AOSP variants. 189 public static final int EXTENDED_CONTAINERS = -200; 190 191 public static final int CONTAINER_UNKNOWN = -1; 192 containerToString(int container)193 public static final String containerToString(int container) { 194 switch (container) { 195 case CONTAINER_DESKTOP: return "desktop"; 196 case CONTAINER_HOTSEAT: return "hotseat"; 197 case CONTAINER_PREDICTION: return "prediction"; 198 case CONTAINER_ALL_APPS: return "all_apps"; 199 case CONTAINER_WIDGETS_TRAY: return "widgets_tray"; 200 case CONTAINER_SHORTCUTS: return "shortcuts"; 201 default: return String.valueOf(container); 202 } 203 } 204 itemTypeToString(int type)205 public static final String itemTypeToString(int type) { 206 switch(type) { 207 case ITEM_TYPE_APPLICATION: return "APP"; 208 case ITEM_TYPE_FOLDER: return "FOLDER"; 209 case ITEM_TYPE_APPWIDGET: return "WIDGET"; 210 case ITEM_TYPE_CUSTOM_APPWIDGET: return "CUSTOMWIDGET"; 211 case ITEM_TYPE_DEEP_SHORTCUT: return "DEEPSHORTCUT"; 212 case ITEM_TYPE_TASK: return "TASK"; 213 case ITEM_TYPE_QSB: return "QSB"; 214 case ITEM_TYPE_APP_PAIR: return "APP_PAIR"; 215 case ITEM_TYPE_PRIVATE_SPACE_INSTALL_APP_BUTTON: 216 return "PRIVATE_SPACE_INSTALL_APP_BUTTON"; 217 default: return String.valueOf(type); 218 } 219 } 220 221 /** 222 * The screen holding the favorite (if container is CONTAINER_DESKTOP) 223 * <P>Type: INTEGER</P> 224 */ 225 public static final String SCREEN = "screen"; 226 227 /** 228 * The X coordinate of the cell holding the favorite 229 * (if container is CONTAINER_HOTSEAT or CONTAINER_HOTSEAT) 230 * <P>Type: INTEGER</P> 231 */ 232 public static final String CELLX = "cellX"; 233 234 /** 235 * The Y coordinate of the cell holding the favorite 236 * (if container is CONTAINER_DESKTOP) 237 * <P>Type: INTEGER</P> 238 */ 239 public static final String CELLY = "cellY"; 240 241 /** 242 * The X span of the cell holding the favorite 243 * <P>Type: INTEGER</P> 244 */ 245 public static final String SPANX = "spanX"; 246 247 /** 248 * The Y span of the cell holding the favorite 249 * <P>Type: INTEGER</P> 250 */ 251 public static final String SPANY = "spanY"; 252 253 /** 254 * The profile id of the item in the cell. 255 * <P> 256 * Type: INTEGER 257 * </P> 258 */ 259 public static final String PROFILE_ID = "profileId"; 260 261 /** 262 * The appWidgetId of the widget 263 * 264 * <P>Type: INTEGER</P> 265 */ 266 public static final String APPWIDGET_ID = "appWidgetId"; 267 268 /** 269 * The ComponentName of the widget provider 270 * 271 * <P>Type: STRING</P> 272 */ 273 public static final String APPWIDGET_PROVIDER = "appWidgetProvider"; 274 275 /** 276 * Boolean indicating that his item was restored and not yet successfully bound. 277 * <P>Type: INTEGER</P> 278 */ 279 public static final String RESTORED = "restored"; 280 281 /** 282 * Indicates the position of the item inside an auto-arranged view like folder or hotseat. 283 * <p>Type: INTEGER</p> 284 */ 285 public static final String RANK = "rank"; 286 287 /** 288 * Stores general flag based options for {@link ItemInfo}s. 289 * <p>Type: INTEGER</p> 290 */ 291 public static final String OPTIONS = "options"; 292 293 /** 294 * Stores the source container that the widget was added from. 295 * <p>Type: INTEGER</p> 296 */ 297 public static final String APPWIDGET_SOURCE = "appWidgetSource"; 298 addTableToDb(SQLiteDatabase db, long myProfileId, boolean optional)299 public static void addTableToDb(SQLiteDatabase db, long myProfileId, boolean optional) { 300 addTableToDb(db, myProfileId, optional, TABLE_NAME); 301 } 302 addTableToDb(SQLiteDatabase db, long myProfileId, boolean optional, String tableName)303 public static void addTableToDb(SQLiteDatabase db, long myProfileId, boolean optional, 304 String tableName) { 305 db.execSQL("CREATE TABLE " + (optional ? " IF NOT EXISTS " : "") + tableName + " (" 306 + getJoinedColumnsToTypes(myProfileId) + ");"); 307 } 308 309 // LinkedHashMap maintains Order of Insertion 310 @NonNull getColumnsToTypes(long profileId)311 private static LinkedHashMap<String, String> getColumnsToTypes(long profileId) { 312 final LinkedHashMap<String, String> columnsToTypes = new LinkedHashMap<>(); 313 columnsToTypes.put(_ID, "INTEGER PRIMARY KEY"); 314 columnsToTypes.put(TITLE, "TEXT"); 315 columnsToTypes.put(INTENT, "TEXT"); 316 columnsToTypes.put(CONTAINER, "INTEGER"); 317 columnsToTypes.put(SCREEN, "INTEGER"); 318 columnsToTypes.put(CELLX, "INTEGER"); 319 columnsToTypes.put(CELLY, "INTEGER"); 320 columnsToTypes.put(SPANX, "INTEGER"); 321 columnsToTypes.put(SPANY, "INTEGER"); 322 columnsToTypes.put(ITEM_TYPE, "INTEGER"); 323 columnsToTypes.put(APPWIDGET_ID, "INTEGER NOT NULL DEFAULT -1"); 324 columnsToTypes.put(ICON, "BLOB"); 325 columnsToTypes.put(APPWIDGET_PROVIDER, "TEXT"); 326 columnsToTypes.put(MODIFIED, "INTEGER NOT NULL DEFAULT 0"); 327 columnsToTypes.put(RESTORED, "INTEGER NOT NULL DEFAULT 0"); 328 columnsToTypes.put(PROFILE_ID, "INTEGER DEFAULT " + profileId); 329 columnsToTypes.put(RANK, "INTEGER NOT NULL DEFAULT 0"); 330 columnsToTypes.put(OPTIONS, "INTEGER NOT NULL DEFAULT 0"); 331 columnsToTypes.put(APPWIDGET_SOURCE, "INTEGER NOT NULL DEFAULT -1"); 332 return columnsToTypes; 333 } 334 getJoinedColumnsToTypes(long profileId)335 private static String getJoinedColumnsToTypes(long profileId) { 336 return getColumnsToTypes(profileId) 337 .entrySet() 338 .stream() 339 .map(it -> it.getKey() + " " + it.getValue()) 340 .collect(Collectors.joining(", ")); 341 } 342 343 /** 344 * Returns an ordered list of columns in the Favorites table as one string, ready to use in 345 * an SQL statement. 346 */ 347 @NonNull getColumns(long profileId)348 public static String getColumns(long profileId) { 349 return String.join(", ", getColumnsToTypes(profileId).keySet()); 350 } 351 } 352 353 /** 354 * Launcher settings 355 */ 356 public static final class Settings { 357 public static final String LAYOUT_DIGEST_KEY = "launcher3.layout.provider.blob"; 358 public static final String LAYOUT_DIGEST_LABEL = "launcher-layout"; 359 public static final String LAYOUT_DIGEST_TAG = "ignore"; 360 } 361 } 362