Home | History | Annotate | Download | only in launcher2
      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