Java Code Examples for android.content.pm.ShortcutInfo#getActivity()

The following examples show how to use android.content.pm.ShortcutInfo#getActivity() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ShortcutPackage.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
/**
 * Build a list of shortcuts for each target activity and return as a map. The result won't
 * contain "floating" shortcuts because they don't belong on any activities.
 */
private ArrayMap<ComponentName, ArrayList<ShortcutInfo>> sortShortcutsToActivities() {
    final ArrayMap<ComponentName, ArrayList<ShortcutInfo>> activitiesToShortcuts
            = new ArrayMap<>();
    for (int i = mShortcuts.size() - 1; i >= 0; i--) {
        final ShortcutInfo si = mShortcuts.valueAt(i);
        if (si.isFloating()) {
            continue; // Ignore floating shortcuts, which are not tied to any activities.
        }

        final ComponentName activity = si.getActivity();
        if (activity == null) {
            mShortcutUser.mService.wtf("null activity detected.");
            continue;
        }

        ArrayList<ShortcutInfo> list = activitiesToShortcuts.get(activity);
        if (list == null) {
            list = new ArrayList<>();
            activitiesToShortcuts.put(activity, list);
        }
        list.add(si);
    }
    return activitiesToShortcuts;
}
 
Example 2
Source File: ShortcutService.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
/**
 * When a shortcut has no target activity, set the default one from the package.
 */
private void fillInDefaultActivity(List<ShortcutInfo> shortcuts) {
    ComponentName defaultActivity = null;
    for (int i = shortcuts.size() - 1; i >= 0; i--) {
        final ShortcutInfo si = shortcuts.get(i);
        if (si.getActivity() == null) {
            if (defaultActivity == null) {
                defaultActivity = injectGetDefaultMainActivity(
                        si.getPackage(), si.getUserId());
                Preconditions.checkState(defaultActivity != null,
                        "Launcher activity not found for package " + si.getPackage());
            }
            si.setActivity(defaultActivity);
        }
    }
}
 
Example 3
Source File: ShortcutPackage.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/**
 * @return false if any of the target activities are no longer enabled.
 */
private boolean areAllActivitiesStillEnabled() {
    if (mShortcuts.size() == 0) {
        return true;
    }
    final ShortcutService s = mShortcutUser.mService;

    // Normally the number of target activities is 1 or so, so no need to use a complex
    // structure like a set.
    final ArrayList<ComponentName> checked = new ArrayList<>(4);

    for (int i = mShortcuts.size() - 1; i >= 0; i--) {
        final ShortcutInfo si = mShortcuts.valueAt(i);
        final ComponentName activity = si.getActivity();

        if (checked.contains(activity)) {
            continue; // Already checked.
        }
        checked.add(activity);

        if ((activity != null)
                && !s.injectIsActivityEnabledAndExported(activity, getOwnerUserId())) {
            return false;
        }
    }
    return true;
}
 
Example 4
Source File: ShortcutService.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/**
 * Clean up / validate an incoming shortcut.
 * - Make sure all mandatory fields are set.
 * - Make sure the intent's extras are persistable, and them to set
 * {@link ShortcutInfo#mIntentPersistableExtrases}.  Also clear its extras.
 * - Clear flags.
 */
private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate,
        boolean forPinRequest) {
    if (shortcut.isReturnedByServer()) {
        Log.w(TAG,
                "Re-publishing ShortcutInfo returned by server is not supported."
                + " Some information such as icon may lost from shortcut.");
    }
    Preconditions.checkNotNull(shortcut, "Null shortcut detected");
    if (shortcut.getActivity() != null) {
        Preconditions.checkState(
                shortcut.getPackage().equals(shortcut.getActivity().getPackageName()),
                "Cannot publish shortcut: activity " + shortcut.getActivity() + " does not"
                + " belong to package " + shortcut.getPackage());
        Preconditions.checkState(
                injectIsMainActivity(shortcut.getActivity(), shortcut.getUserId()),
                "Cannot publish shortcut: activity " + shortcut.getActivity() + " is not"
                        + " main activity");
    }

    if (!forUpdate) {
        shortcut.enforceMandatoryFields(/* forPinned= */ forPinRequest);
        if (!forPinRequest) {
            Preconditions.checkState(shortcut.getActivity() != null,
                    "Cannot publish shortcut: target activity is not set");
        }
    }
    if (shortcut.getIcon() != null) {
        ShortcutInfo.validateIcon(shortcut.getIcon());
    }

    shortcut.replaceFlags(0);
}
 
Example 5
Source File: ActionMenu.java    From LaunchTime with GNU General Public License v3.0 5 votes vote down vote up
private void addShortcutToActionPopup(final LauncherApps launcherApps, final ShortcutInfo shortcutInfo) {
    if (Build.VERSION.SDK_INT>=25) {
        if (shortcutInfo != null && shortcutInfo.getActivity() != null) {
            //Log.d(TAG, shortcutInfo.getShortLabel() + " " + shortcutInfo.getActivity().getClassName());

            if (shortcutInfo.isEnabled()) {

                String label = "";
                if (shortcutInfo.getShortLabel() != null)
                    label += shortcutInfo.getShortLabel();

                if (shortcutInfo.getLongLabel() != null && !label.contentEquals(shortcutInfo.getLongLabel()))
                    label = shortcutInfo.getLongLabel() + "";

                Drawable icon = launcherApps.getShortcutIconDrawable(shortcutInfo, DisplayMetrics.DENSITY_DEFAULT);
                addActionMenuItem(label.trim(), icon, new Runnable() {
                    @Override
                    public void run() {
                        if (Build.VERSION.SDK_INT >= 25) {
                            try {
                                launcherApps.startShortcut(shortcutInfo, null, null);
                            } catch (Exception e) {
                                Log.e(TAG, "Couldn't Launch shortcut", e);
                            }
                        }
                        dismissActionPopup();
                    }
                });

            }
        }
    }
}
 
Example 6
Source File: ShortcutRequestPinProcessor.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
/**
 * Handle {@link android.content.pm.ShortcutManager#requestPinShortcut)}.
 */
@NonNull
private PinItemRequest requestPinShortcutLocked(ShortcutInfo inShortcut,
        IntentSender resultIntentOriginal, Pair<ComponentName, Integer> confirmActivity) {
    final ShortcutPackage ps = mService.getPackageShortcutsForPublisherLocked(
            inShortcut.getPackage(), inShortcut.getUserId());

    final ShortcutInfo existing = ps.findShortcutById(inShortcut.getId());
    final boolean existsAlready = existing != null;
    final boolean existingIsVisible = existsAlready && existing.isVisibleToPublisher();

    if (DEBUG) {
        Slog.d(TAG, "requestPinnedShortcut: package=" + inShortcut.getPackage()
                + " existsAlready=" + existsAlready
                + " existingIsVisible=" + existingIsVisible
                + " shortcut=" + inShortcut.toInsecureString());
    }

    // This is the shortcut that'll be sent to the launcher.
    final ShortcutInfo shortcutForLauncher;
    final String launcherPackage = confirmActivity.first.getPackageName();
    final int launcherUserId = confirmActivity.second;

    IntentSender resultIntentToSend = resultIntentOriginal;

    if (existsAlready) {
        validateExistingShortcut(existing);

        final boolean isAlreadyPinned = mService.getLauncherShortcutsLocked(
                launcherPackage, existing.getUserId(), launcherUserId).hasPinned(existing);
        if (isAlreadyPinned) {
            // When the shortcut is already pinned by this launcher, the request will always
            // succeed, so just send the result at this point.
            sendResultIntent(resultIntentOriginal, null);

            // So, do not send the intent again.
            resultIntentToSend = null;
        }

        // Pass a clone, not the original.
        // Note this will remove the intent and icons.
        shortcutForLauncher = existing.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);

        if (!isAlreadyPinned) {
            // FLAG_PINNED may still be set, if it's pinned by other launchers.
            shortcutForLauncher.clearFlags(ShortcutInfo.FLAG_PINNED);
        }
    } else {
        // If the shortcut has no default activity, try to set the main activity.
        // But in the request-pin case, it's optional, so it's okay even if the caller
        // has no default activity.
        if (inShortcut.getActivity() == null) {
            inShortcut.setActivity(mService.injectGetDefaultMainActivity(
                    inShortcut.getPackage(), inShortcut.getUserId()));
        }

        // It doesn't exist, so it must have all mandatory fields.
        mService.validateShortcutForPinRequest(inShortcut);

        // Initialize the ShortcutInfo for pending approval.
        inShortcut.resolveResourceStrings(mService.injectGetResourcesForApplicationAsUser(
                inShortcut.getPackage(), inShortcut.getUserId()));
        if (DEBUG) {
            Slog.d(TAG, "Resolved shortcut=" + inShortcut.toInsecureString());
        }
        // We should strip out the intent, but should preserve the icon.
        shortcutForLauncher = inShortcut.clone(
                ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER_APPROVAL);
    }
    if (DEBUG) {
        Slog.d(TAG, "Sending to launcher=" + shortcutForLauncher.toInsecureString());
    }

    // Create a request object.
    final PinShortcutRequestInner inner =
            new PinShortcutRequestInner(this, inShortcut, shortcutForLauncher,
                    resultIntentToSend, launcherPackage, launcherUserId,
                    mService.injectGetPackageUid(launcherPackage, launcherUserId),
                    existsAlready);

    return new PinItemRequest(inner, PinItemRequest.REQUEST_TYPE_SHORTCUT);
}
 
Example 7
Source File: ShortcutRequestPinProcessor.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
/**
 * The last step of the "request pin shortcut" flow.  Called when the launcher accepted a
 * request.
 */
public boolean directPinShortcut(PinShortcutRequestInner request) {

    final ShortcutInfo original = request.shortcutOriginal;
    final int appUserId = original.getUserId();
    final String appPackageName = original.getPackage();
    final int launcherUserId = request.launcherUserId;
    final String launcherPackage = request.launcherPackage;
    final String shortcutId = original.getId();

    synchronized (mLock) {
        if (!(mService.isUserUnlockedL(appUserId)
                && mService.isUserUnlockedL(request.launcherUserId))) {
            Log.w(TAG, "User is locked now.");
            return false;
        }

        final ShortcutLauncher launcher = mService.getLauncherShortcutsLocked(
                launcherPackage, appUserId, launcherUserId);
        launcher.attemptToRestoreIfNeededAndSave();
        if (launcher.hasPinned(original)) {
            if (DEBUG) {
                Slog.d(TAG, "Shortcut " + original + " already pinned.");                       // This too.
            }
            return true;
        }

        final ShortcutPackage ps = mService.getPackageShortcutsForPublisherLocked(
                appPackageName, appUserId);
        final ShortcutInfo current = ps.findShortcutById(shortcutId);

        // The shortcut might have been changed, so we need to do the same validation again.
        try {
            if (current == null) {
                // It doesn't exist, so it must have all necessary fields.
                mService.validateShortcutForPinRequest(original);
            } else {
                validateExistingShortcut(current);
            }
        } catch (RuntimeException e) {
            Log.w(TAG, "Unable to pin shortcut: " + e.getMessage());
            return false;
        }

        // If the shortcut doesn't exist, need to create it.
        // First, create it as a dynamic shortcut.
        if (current == null) {
            if (DEBUG) {
                Slog.d(TAG, "Temporarily adding " + shortcutId + " as dynamic");
            }
            // Add as a dynamic shortcut.  In order for a shortcut to be dynamic, it must
            // have a target activity, so we set a dummy here.  It's later removed
            // in deleteDynamicWithId().
            if (original.getActivity() == null) {
                original.setActivity(mService.getDummyMainActivity(appPackageName));
            }
            ps.addOrReplaceDynamicShortcut(original);
        }

        // Pin the shortcut.
        if (DEBUG) {
            Slog.d(TAG, "Pinning " + shortcutId);
        }

        launcher.addPinnedShortcut(appPackageName, appUserId, shortcutId,
                /*forPinRequest=*/ true);

        if (current == null) {
            if (DEBUG) {
                Slog.d(TAG, "Removing " + shortcutId + " as dynamic");
            }
            ps.deleteDynamicWithId(shortcutId, /*ignoreInvisible=*/ false);
        }

        ps.adjustRanks(); // Shouldn't be needed, but just in case.
    }

    mService.verifyStates();
    mService.packageShortcutsChanged(appPackageName, appUserId);

    return true;
}
 
Example 8
Source File: ShortcutPackage.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
/**
 * Called by
 * {@link android.content.pm.ShortcutManager#setDynamicShortcuts},
 * {@link android.content.pm.ShortcutManager#addDynamicShortcuts}, and
 * {@link android.content.pm.ShortcutManager#updateShortcuts} before actually performing
 * the operation to make sure the operation wouldn't result in the target activities having
 * more than the allowed number of dynamic/manifest shortcuts.
 *
 * @param newList shortcut list passed to set, add or updateShortcuts().
 * @param operation add, set or update.
 * @throws IllegalArgumentException if the operation would result in going over the max
 *                                  shortcut count for any activity.
 */
public void enforceShortcutCountsBeforeOperation(List<ShortcutInfo> newList,
        @ShortcutOperation int operation) {
    final ShortcutService service = mShortcutUser.mService;

    // Current # of dynamic / manifest shortcuts for each activity.
    // (If it's for update, then don't count dynamic shortcuts, since they'll be replaced
    // anyway.)
    final ArrayMap<ComponentName, Integer> counts = new ArrayMap<>(4);
    for (int i = mShortcuts.size() - 1; i >= 0; i--) {
        final ShortcutInfo shortcut = mShortcuts.valueAt(i);

        if (shortcut.isManifestShortcut()) {
            incrementCountForActivity(counts, shortcut.getActivity(), 1);
        } else if (shortcut.isDynamic() && (operation != ShortcutService.OPERATION_SET)) {
            incrementCountForActivity(counts, shortcut.getActivity(), 1);
        }
    }

    for (int i = newList.size() - 1; i >= 0; i--) {
        final ShortcutInfo newShortcut = newList.get(i);
        final ComponentName newActivity = newShortcut.getActivity();
        if (newActivity == null) {
            if (operation != ShortcutService.OPERATION_UPDATE) {
                service.wtf("Activity must not be null at this point");
                continue; // Just ignore this invalid case.
            }
            continue; // Activity can be null for update.
        }

        final ShortcutInfo original = mShortcuts.get(newShortcut.getId());
        if (original == null) {
            if (operation == ShortcutService.OPERATION_UPDATE) {
                continue; // When updating, ignore if there's no target.
            }
            // Add() or set(), and there's no existing shortcut with the same ID.  We're
            // simply publishing (as opposed to updating) this shortcut, so just +1.
            incrementCountForActivity(counts, newActivity, 1);
            continue;
        }
        if (original.isFloating() && (operation == ShortcutService.OPERATION_UPDATE)) {
            // Updating floating shortcuts doesn't affect the count, so ignore.
            continue;
        }

        // If it's add() or update(), then need to decrement for the previous activity.
        // Skip it for set() since it's already been taken care of by not counting the original
        // dynamic shortcuts in the first loop.
        if (operation != ShortcutService.OPERATION_SET) {
            final ComponentName oldActivity = original.getActivity();
            if (!original.isFloating()) {
                incrementCountForActivity(counts, oldActivity, -1);
            }
        }
        incrementCountForActivity(counts, newActivity, 1);
    }

    // Then make sure none of the activities have more than the max number of shortcuts.
    for (int i = counts.size() - 1; i >= 0; i--) {
        service.enforceMaxActivityShortcuts(counts.valueAt(i));
    }
}