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.content.ContentValues; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.graphics.Bitmap; 23 import android.util.Log; 24 25 import com.android.launcher3.compat.UserHandleCompat; 26 import com.android.launcher3.compat.UserManagerCompat; 27 28 import java.io.ByteArrayOutputStream; 29 import java.io.IOException; 30 import java.util.Arrays; 31 32 /** 33 * Represents an item in the launcher. 34 */ 35 public class ItemInfo { 36 37 /** 38 * Intent extra to store the profile. Format: UserHandle 39 */ 40 static final String EXTRA_PROFILE = "profile"; 41 42 static final int NO_ID = -1; 43 44 /** 45 * The id in the settings database for this item 46 */ 47 public long id = NO_ID; 48 49 /** 50 * One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION}, 51 * {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT}, 52 * {@link LauncherSettings.Favorites#ITEM_TYPE_FOLDER}, or 53 * {@link LauncherSettings.Favorites#ITEM_TYPE_APPWIDGET}. 54 */ 55 public int itemType; 56 57 /** 58 * The id of the container that holds this item. For the desktop, this will be 59 * {@link LauncherSettings.Favorites#CONTAINER_DESKTOP}. For the all applications folder it 60 * will be {@link #NO_ID} (since it is not stored in the settings DB). For user folders 61 * it will be the id of the folder. 62 */ 63 public long container = NO_ID; 64 65 /** 66 * Iindicates the screen in which the shortcut appears. 67 */ 68 public long screenId = -1; 69 70 /** 71 * Indicates the X position of the associated cell. 72 */ 73 public int cellX = -1; 74 75 /** 76 * Indicates the Y position of the associated cell. 77 */ 78 public int cellY = -1; 79 80 /** 81 * Indicates the X cell span. 82 */ 83 public int spanX = 1; 84 85 /** 86 * Indicates the Y cell span. 87 */ 88 int spanY = 1; 89 90 /** 91 * Indicates the minimum X cell span. 92 */ 93 public int minSpanX = 1; 94 95 /** 96 * Indicates the minimum Y cell span. 97 */ 98 public int minSpanY = 1; 99 100 /** 101 * Indicates that this item needs to be updated in the db 102 */ 103 public boolean requiresDbUpdate = false; 104 105 /** 106 * Title of the item 107 */ 108 CharSequence title; 109 110 /** 111 * Content description of the item. 112 */ 113 CharSequence contentDescription; 114 115 /** 116 * The position of the item in a drag-and-drop operation. 117 */ 118 int[] dropPos = null; 119 120 UserHandleCompat user; 121 122 ItemInfo() { 123 user = UserHandleCompat.myUserHandle(); 124 } 125 126 ItemInfo(ItemInfo info) { 127 copyFrom(info); 128 // tempdebug: 129 LauncherModel.checkItemInfo(this); 130 } 131 132 public void copyFrom(ItemInfo info) { 133 id = info.id; 134 cellX = info.cellX; 135 cellY = info.cellY; 136 spanX = info.spanX; 137 spanY = info.spanY; 138 screenId = info.screenId; 139 itemType = info.itemType; 140 container = info.container; 141 user = info.user; 142 contentDescription = info.contentDescription; 143 } 144 145 public Intent getIntent() { 146 throw new RuntimeException("Unexpected Intent"); 147 } 148 149 /** 150 * Write the fields of this item to the DB 151 * 152 * @param context A context object to use for getting UserManagerCompat 153 * @param values 154 */ 155 156 void onAddToDatabase(Context context, ContentValues values) { 157 values.put(LauncherSettings.BaseLauncherColumns.ITEM_TYPE, itemType); 158 values.put(LauncherSettings.Favorites.CONTAINER, container); 159 values.put(LauncherSettings.Favorites.SCREEN, screenId); 160 values.put(LauncherSettings.Favorites.CELLX, cellX); 161 values.put(LauncherSettings.Favorites.CELLY, cellY); 162 values.put(LauncherSettings.Favorites.SPANX, spanX); 163 values.put(LauncherSettings.Favorites.SPANY, spanY); 164 long serialNumber = UserManagerCompat.getInstance(context).getSerialNumberForUser(user); 165 values.put(LauncherSettings.Favorites.PROFILE_ID, serialNumber); 166 167 if (screenId == Workspace.EXTRA_EMPTY_SCREEN_ID) { 168 // We should never persist an item on the extra empty screen. 169 throw new RuntimeException("Screen id should not be EXTRA_EMPTY_SCREEN_ID"); 170 } 171 } 172 173 void updateValuesWithCoordinates(ContentValues values, int cellX, int cellY) { 174 values.put(LauncherSettings.Favorites.CELLX, cellX); 175 values.put(LauncherSettings.Favorites.CELLY, cellY); 176 } 177 178 static byte[] flattenBitmap(Bitmap bitmap) { 179 // Try go guesstimate how much space the icon will take when serialized 180 // to avoid unnecessary allocations/copies during the write. 181 int size = bitmap.getWidth() * bitmap.getHeight() * 4; 182 ByteArrayOutputStream out = new ByteArrayOutputStream(size); 183 try { 184 bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); 185 out.flush(); 186 out.close(); 187 return out.toByteArray(); 188 } catch (IOException e) { 189 Log.w("Favorite", "Could not write icon"); 190 return null; 191 } 192 } 193 194 static void writeBitmap(ContentValues values, Bitmap bitmap) { 195 if (bitmap != null) { 196 byte[] data = flattenBitmap(bitmap); 197 values.put(LauncherSettings.Favorites.ICON, data); 198 } 199 } 200 201 /** 202 * It is very important that sub-classes implement this if they contain any references 203 * to the activity (anything in the view hierarchy etc.). If not, leaks can result since 204 * ItemInfo objects persist across rotation and can hence leak by holding stale references 205 * to the old view hierarchy / activity. 206 */ 207 void unbind() { 208 } 209 210 @Override 211 public String toString() { 212 return "Item(id=" + this.id + " type=" + this.itemType + " container=" + this.container 213 + " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX 214 + " spanY=" + spanY + " dropPos=" + Arrays.toString(dropPos) 215 + " user=" + user + ")"; 216 } 217 } 218