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
17package com.android.launcher2;
18
19import java.util.ArrayList;
20
21import android.content.BroadcastReceiver;
22import android.content.Context;
23import android.content.Intent;
24import android.widget.Toast;
25
26import com.android.launcher.R;
27
28public class InstallShortcutReceiver extends BroadcastReceiver {
29    public static final String ACTION_INSTALL_SHORTCUT =
30            "com.android.launcher.action.INSTALL_SHORTCUT";
31
32    // A mime-type representing shortcut data
33    public static final String SHORTCUT_MIMETYPE =
34            "com.android.launcher/shortcut";
35
36    private final int[] mCoordinates = new int[2];
37
38    public void onReceive(Context context, Intent data) {
39        if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) {
40            return;
41        }
42
43        int screen = Launcher.getScreen();
44
45        if (!installShortcut(context, data, screen)) {
46            // The target screen is full, let's try the other screens
47            for (int i = 0; i < Launcher.SCREEN_COUNT; i++) {
48                if (i != screen && installShortcut(context, data, i)) break;
49            }
50        }
51    }
52
53    private boolean installShortcut(Context context, Intent data, int screen) {
54        String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
55
56        if (findEmptyCell(context, mCoordinates, screen)) {
57            Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
58            if (intent != null) {
59                if (intent.getAction() == null) {
60                    intent.setAction(Intent.ACTION_VIEW);
61                }
62
63                // By default, we allow for duplicate entries (located in
64                // different places)
65                boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
66                if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) {
67                    LauncherApplication app = (LauncherApplication) context.getApplicationContext();
68                    ShortcutInfo info = app.getModel().addShortcut(context, data,
69                            LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, mCoordinates[0],
70                            mCoordinates[1], true);
71                    if (info != null) {
72                        Toast.makeText(context, context.getString(R.string.shortcut_installed, name),
73                                Toast.LENGTH_SHORT).show();
74                    } else {
75                        return false;
76                    }
77                } else {
78                    Toast.makeText(context, context.getString(R.string.shortcut_duplicate, name),
79                            Toast.LENGTH_SHORT).show();
80                }
81
82                return true;
83            }
84        } else {
85            Toast.makeText(context, context.getString(R.string.out_of_space),
86                    Toast.LENGTH_SHORT).show();
87        }
88
89        return false;
90    }
91
92    private static boolean findEmptyCell(Context context, int[] xy, int screen) {
93        final int xCount = LauncherModel.getCellCountX();
94        final int yCount = LauncherModel.getCellCountY();
95        boolean[][] occupied = new boolean[xCount][yCount];
96
97        ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
98        ItemInfo item = null;
99        int cellX, cellY, spanX, spanY;
100        for (int i = 0; i < items.size(); ++i) {
101            item = items.get(i);
102            if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
103                if (item.screen == screen) {
104                    cellX = item.cellX;
105                    cellY = item.cellY;
106                    spanX = item.spanX;
107                    spanY = item.spanY;
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            }
115        }
116
117        return CellLayout.findVacantCell(xy, 1, 1, xCount, yCount, occupied);
118    }
119}
120