blob: 189e51ddbda0977710597218bcdd58410a2584dc [file] [log] [blame]
/**
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.support.v4.content.pm;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
/**
* Helper for accessing features in {@link android.content.pm.ShortcutManager}.
*/
public class ShortcutManagerCompat {
@VisibleForTesting static final String ACTION_INSTALL_SHORTCUT =
"com.android.launcher.action.INSTALL_SHORTCUT";
@VisibleForTesting static final String INSTALL_SHORTCUT_PERMISSION =
"com.android.launcher.permission.INSTALL_SHORTCUT";
private ShortcutManagerCompat() {
/* Hide constructor */
}
/**
* @return {@code true} if the launcher supports {@link #requestPinShortcut},
* {@code false} otherwise
*/
public static boolean isRequestPinShortcutSupported(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 26) {
return context.getSystemService(ShortcutManager.class).isRequestPinShortcutSupported();
}
if (ContextCompat.checkSelfPermission(context, INSTALL_SHORTCUT_PERMISSION)
!= PackageManager.PERMISSION_GRANTED) {
return false;
}
for (ResolveInfo info : context.getPackageManager().queryBroadcastReceivers(
new Intent(ACTION_INSTALL_SHORTCUT), 0)) {
String permission = info.activityInfo.permission;
if (TextUtils.isEmpty(permission) || INSTALL_SHORTCUT_PERMISSION.equals(permission)) {
return true;
}
}
return false;
}
/**
* Request to create a pinned shortcut.
* <p>On API <= 25 it creates a legacy shortcut with the provided icon, label and intent. For
* newer APIs it will create a {@link android.content.pm.ShortcutInfo} object which can be
* updated by the app.
*
* <p>Use {@link android.app.PendingIntent#getIntentSender()} to create a {@link IntentSender}.
*
* @param shortcut new shortcut to pin
* @param callback if not null, this intent will be sent when the shortcut is pinned
*
* @return {@code true} if the launcher supports this feature
*
* @see #isRequestPinShortcutSupported
* @see IntentSender
* @see android.app.PendingIntent#getIntentSender()
*/
public static boolean requestPinShortcut(@NonNull final Context context,
@NonNull ShortcutInfoCompat shortcut, @Nullable final IntentSender callback) {
if (Build.VERSION.SDK_INT >= 26) {
return context.getSystemService(ShortcutManager.class).requestPinShortcut(
shortcut.toShortcutInfo(), callback);
}
if (!isRequestPinShortcutSupported(context)) {
return false;
}
Intent intent = shortcut.addToIntent(new Intent(ACTION_INSTALL_SHORTCUT));
// If the callback is null, just send the broadcast
if (callback == null) {
context.sendBroadcast(intent);
return true;
}
// Otherwise send the callback when the intent has successfully been dispatched.
context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
callback.sendIntent(context, 0, null, null, null);
} catch (IntentSender.SendIntentException e) {
// Ignore
}
}
}, null, Activity.RESULT_OK, null, null);
return true;
}
/**
* Returns an Intent which can be used by the launcher to pin shortcut.
* <p>This should be used by an Activity to set result in response to
* {@link Intent#ACTION_CREATE_SHORTCUT}.
*
* @param shortcut new shortcut to pin
* @return the intent that should be set as the result for the calling activity
*
* @see Intent#ACTION_CREATE_SHORTCUT
*/
@NonNull
public static Intent createShortcutResultIntent(@NonNull Context context,
@NonNull ShortcutInfoCompat shortcut) {
Intent result = null;
if (Build.VERSION.SDK_INT >= 26) {
result = context.getSystemService(ShortcutManager.class)
.createShortcutResultIntent(shortcut.toShortcutInfo());
}
if (result == null) {
result = new Intent();
}
return shortcut.addToIntent(result);
}
}