1/*
2 * Copyright (C) 2017 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.launcher3.compat;
18
19import android.annotation.TargetApi;
20import android.app.Activity;
21import android.content.ActivityNotFoundException;
22import android.content.ComponentName;
23import android.content.Intent;
24import android.content.IntentSender;
25import android.content.pm.ActivityInfo;
26import android.content.pm.LauncherActivityInfo;
27import android.content.pm.LauncherApps;
28import android.content.pm.PackageManager;
29import android.graphics.drawable.Drawable;
30import android.os.Process;
31import android.os.UserHandle;
32import android.util.Log;
33import android.widget.Toast;
34
35import com.android.launcher3.IconCache;
36import com.android.launcher3.LauncherSettings;
37import com.android.launcher3.R;
38import com.android.launcher3.ShortcutInfo;
39
40/**
41 * Wrapper class for representing a shortcut configure activity.
42 */
43public abstract class ShortcutConfigActivityInfo {
44
45    private static final String TAG = "SCActivityInfo";
46
47    private final ComponentName mCn;
48    private final UserHandle mUser;
49
50    protected ShortcutConfigActivityInfo(ComponentName cn, UserHandle user) {
51        mCn = cn;
52        mUser = user;
53    }
54
55    public ComponentName getComponent() {
56        return mCn;
57    }
58
59    public UserHandle getUser() {
60        return mUser;
61    }
62
63    public int getItemType() {
64        return LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
65    }
66
67    public abstract CharSequence getLabel();
68
69    public abstract Drawable getFullResIcon(IconCache cache);
70
71    /**
72     * Return a shortcut info, if it can be created directly on drop, without requiring any
73     * {@link #startConfigActivity(Activity, int)}.
74     */
75    public ShortcutInfo createShortcutInfo() {
76        return null;
77    }
78
79    public boolean startConfigActivity(Activity activity, int requestCode) {
80        Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT)
81                .setComponent(getComponent());
82        try {
83            activity.startActivityForResult(intent, requestCode);
84            return true;
85        } catch (ActivityNotFoundException e) {
86            Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
87        } catch (SecurityException e) {
88            Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
89            Log.e(TAG, "Launcher does not have the permission to launch " + intent +
90                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +
91                    "or use the exported attribute for this activity.", e);
92        }
93        return false;
94    }
95
96    /**
97     * Returns true if various properties ({@link #getLabel()}, {@link #getFullResIcon}) can
98     * be safely persisted.
99     */
100    public boolean isPersistable() {
101        return true;
102    }
103
104    static class ShortcutConfigActivityInfoVL extends ShortcutConfigActivityInfo {
105
106        private final ActivityInfo mInfo;
107        private final PackageManager mPm;
108
109
110        public ShortcutConfigActivityInfoVL(ActivityInfo info, PackageManager pm) {
111            super(new ComponentName(info.packageName, info.name), Process.myUserHandle());
112            mInfo = info;
113            mPm = pm;
114        }
115
116        @Override
117        public CharSequence getLabel() {
118            return mInfo.loadLabel(mPm);
119        }
120
121        @Override
122        public Drawable getFullResIcon(IconCache cache) {
123            return cache.getFullResIcon(mInfo);
124        }
125    }
126
127    @TargetApi(26)
128    public static class ShortcutConfigActivityInfoVO extends ShortcutConfigActivityInfo {
129
130        private final LauncherActivityInfo mInfo;
131
132        public ShortcutConfigActivityInfoVO(LauncherActivityInfo info) {
133            super(info.getComponentName(), info.getUser());
134            mInfo = info;
135        }
136
137        @Override
138        public CharSequence getLabel() {
139            return mInfo.getLabel();
140        }
141
142        @Override
143        public Drawable getFullResIcon(IconCache cache) {
144            return cache.getFullResIcon(mInfo);
145        }
146
147        @Override
148        public boolean startConfigActivity(Activity activity, int requestCode) {
149            if (getUser().equals(Process.myUserHandle())) {
150                return super.startConfigActivity(activity, requestCode);
151            }
152            IntentSender is = activity.getSystemService(LauncherApps.class)
153                    .getShortcutConfigActivityIntent(mInfo);
154            try {
155                activity.startIntentSenderForResult(is, requestCode, null, 0, 0, 0);
156                return true;
157            } catch (IntentSender.SendIntentException e) {
158                Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
159                return false;
160            }
161        }
162    }
163}
164