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.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.ContentResolver; 23 import android.database.Cursor; 24 import android.widget.Toast; 25 26 import com.android.launcher.R; 27 28 public class InstallShortcutReceiver extends BroadcastReceiver { 29 private static final String ACTION_INSTALL_SHORTCUT = 30 "com.android.launcher.action.INSTALL_SHORTCUT"; 31 32 private final int[] mCoordinates = new int[2]; 33 34 public void onReceive(Context context, Intent data) { 35 if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) { 36 return; 37 } 38 39 int screen = Launcher.getScreen(); 40 41 if (!installShortcut(context, data, screen)) { 42 // The target screen is full, let's try the other screens 43 for (int i = 0; i < Launcher.SCREEN_COUNT; i++) { 44 if (i != screen && installShortcut(context, data, i)) break; 45 } 46 } 47 } 48 49 private boolean installShortcut(Context context, Intent data, int screen) { 50 String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); 51 52 if (findEmptyCell(context, mCoordinates, screen)) { 53 CellLayout.CellInfo cell = new CellLayout.CellInfo(); 54 cell.cellX = mCoordinates[0]; 55 cell.cellY = mCoordinates[1]; 56 cell.screen = screen; 57 58 Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 59 60 if (intent.getAction() == null) { 61 intent.setAction(Intent.ACTION_VIEW); 62 } 63 64 // By default, we allow for duplicate entries (located in 65 // different places) 66 boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true); 67 if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) { 68 ((LauncherApplication)context.getApplicationContext()).getModel() 69 .addShortcut(context, data, cell, true); 70 Toast.makeText(context, context.getString(R.string.shortcut_installed, name), 71 Toast.LENGTH_SHORT).show(); 72 } else { 73 Toast.makeText(context, context.getString(R.string.shortcut_duplicate, name), 74 Toast.LENGTH_SHORT).show(); 75 } 76 77 return true; 78 } else { 79 Toast.makeText(context, context.getString(R.string.out_of_space), 80 Toast.LENGTH_SHORT).show(); 81 } 82 83 return false; 84 } 85 86 private static boolean findEmptyCell(Context context, int[] xy, int screen) { 87 final int xCount = Launcher.NUMBER_CELLS_X; 88 final int yCount = Launcher.NUMBER_CELLS_Y; 89 90 boolean[][] occupied = new boolean[xCount][yCount]; 91 92 final ContentResolver cr = context.getContentResolver(); 93 Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, 94 new String[] { LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY, 95 LauncherSettings.Favorites.SPANX, LauncherSettings.Favorites.SPANY }, 96 LauncherSettings.Favorites.SCREEN + "=?", 97 new String[] { String.valueOf(screen) }, null); 98 99 final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); 100 final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); 101 final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX); 102 final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY); 103 104 try { 105 while (c.moveToNext()) { 106 int cellX = c.getInt(cellXIndex); 107 int cellY = c.getInt(cellYIndex); 108 int spanX = c.getInt(spanXIndex); 109 int spanY = c.getInt(spanYIndex); 110 111 for (int x = cellX; x < cellX + spanX && x < xCount; x++) { 112 for (int y = cellY; y < cellY + spanY && y < yCount; y++) { 113 occupied[x][y] = true; 114 } 115 } 116 } 117 } catch (Exception e) { 118 return false; 119 } finally { 120 c.close(); 121 } 122 123 return CellLayout.findVacantCell(xy, 1, 1, xCount, yCount, occupied); 124 } 125 } 126