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