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.launcher2; 18 19 import android.content.ContentValues; 20 import android.content.Intent; 21 import android.graphics.Bitmap; 22 import android.util.Log; 23 24 import java.io.ByteArrayOutputStream; 25 import java.io.IOException; 26 27 /** 28 * Represents an item in the launcher. 29 */ 30 class ItemInfo { 31 32 static final int NO_ID = -1; 33 34 /** 35 * The id in the settings database for this item 36 */ 37 long id = NO_ID; 38 39 /** 40 * One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION}, 41 * {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT}, 42 * {@link LauncherSettings.Favorites#ITEM_TYPE_FOLDER}, or 43 * {@link LauncherSettings.Favorites#ITEM_TYPE_APPWIDGET}. 44 */ 45 int itemType; 46 47 /** 48 * The id of the container that holds this item. For the desktop, this will be 49 * {@link LauncherSettings.Favorites#CONTAINER_DESKTOP}. For the all applications folder it 50 * will be {@link #NO_ID} (since it is not stored in the settings DB). For user folders 51 * it will be the id of the folder. 52 */ 53 long container = NO_ID; 54 55 /** 56 * Iindicates the screen in which the shortcut appears. 57 */ 58 int screen = -1; 59 60 /** 61 * Indicates the X position of the associated cell. 62 */ 63 int cellX = -1; 64 65 /** 66 * Indicates the Y position of the associated cell. 67 */ 68 int cellY = -1; 69 70 /** 71 * Indicates the X cell span. 72 */ 73 int spanX = 1; 74 75 /** 76 * Indicates the Y cell span. 77 */ 78 int spanY = 1; 79 80 /** 81 * Indicates the minimum X cell span. 82 */ 83 int minSpanX = 1; 84 85 /** 86 * Indicates the minimum Y cell span. 87 */ 88 int minSpanY = 1; 89 /** 90 * Indicates whether the item is a gesture. 91 */ 92 boolean isGesture = false; 93 94 /** 95 * The position of the item in a drag-and-drop operation. 96 */ 97 int[] dropPos = null; 98 ItemInfo()99 ItemInfo() { 100 } 101 ItemInfo(ItemInfo info)102 ItemInfo(ItemInfo info) { 103 id = info.id; 104 cellX = info.cellX; 105 cellY = info.cellY; 106 spanX = info.spanX; 107 spanY = info.spanY; 108 screen = info.screen; 109 itemType = info.itemType; 110 container = info.container; 111 } 112 113 /** Returns the package name that the intent will resolve to, or an empty string if 114 * none exists. */ getPackageName(Intent intent)115 static String getPackageName(Intent intent) { 116 if (intent != null) { 117 String packageName = intent.getPackage(); 118 if (packageName == null && intent.getComponent() != null) { 119 packageName = intent.getComponent().getPackageName(); 120 } 121 if (packageName != null) { 122 return packageName; 123 } 124 } 125 return ""; 126 } 127 128 /** 129 * Write the fields of this item to the DB 130 * 131 * @param values 132 */ onAddToDatabase(ContentValues values)133 void onAddToDatabase(ContentValues values) { 134 values.put(LauncherSettings.BaseLauncherColumns.ITEM_TYPE, itemType); 135 if (!isGesture) { 136 values.put(LauncherSettings.Favorites.CONTAINER, container); 137 values.put(LauncherSettings.Favorites.SCREEN, screen); 138 values.put(LauncherSettings.Favorites.CELLX, cellX); 139 values.put(LauncherSettings.Favorites.CELLY, cellY); 140 values.put(LauncherSettings.Favorites.SPANX, spanX); 141 values.put(LauncherSettings.Favorites.SPANY, spanY); 142 } 143 } 144 updateValuesWithCoordinates(ContentValues values, int cellX, int cellY)145 void updateValuesWithCoordinates(ContentValues values, int cellX, int cellY) { 146 values.put(LauncherSettings.Favorites.CELLX, cellX); 147 values.put(LauncherSettings.Favorites.CELLY, cellY); 148 } 149 flattenBitmap(Bitmap bitmap)150 static byte[] flattenBitmap(Bitmap bitmap) { 151 // Try go guesstimate how much space the icon will take when serialized 152 // to avoid unnecessary allocations/copies during the write. 153 int size = bitmap.getWidth() * bitmap.getHeight() * 4; 154 ByteArrayOutputStream out = new ByteArrayOutputStream(size); 155 try { 156 bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); 157 out.flush(); 158 out.close(); 159 return out.toByteArray(); 160 } catch (IOException e) { 161 Log.w("Favorite", "Could not write icon"); 162 return null; 163 } 164 } 165 writeBitmap(ContentValues values, Bitmap bitmap)166 static void writeBitmap(ContentValues values, Bitmap bitmap) { 167 if (bitmap != null) { 168 byte[] data = flattenBitmap(bitmap); 169 values.put(LauncherSettings.Favorites.ICON, data); 170 } 171 } 172 173 /** 174 * It is very important that sub-classes implement this if they contain any references 175 * to the activity (anything in the view hierarchy etc.). If not, leaks can result since 176 * ItemInfo objects persist across rotation and can hence leak by holding stale references 177 * to the old view hierarchy / activity. 178 */ unbind()179 void unbind() { 180 } 181 182 @Override toString()183 public String toString() { 184 return "Item(id=" + this.id + " type=" + this.itemType + " container=" + this.container 185 + " screen=" + screen + " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX 186 + " spanY=" + spanY + " isGesture=" + isGesture + " dropPos=" + dropPos + ")"; 187 } 188 } 189