| /* |
| * 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 com.android.documentsui; |
| |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.pm.ShortcutInfo; |
| import android.content.pm.ShortcutManager; |
| import android.graphics.drawable.Icon; |
| |
| import androidx.annotation.DrawableRes; |
| |
| import com.android.documentsui.base.Providers; |
| import com.android.documentsui.base.RootInfo; |
| import com.android.documentsui.base.Shared; |
| import com.android.documentsui.files.FilesActivity; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * Manages dynamic shortcuts. |
| */ |
| public final class ShortcutsUpdater { |
| |
| private final Context mContext; |
| |
| public ShortcutsUpdater(Context context) { |
| mContext = context; |
| } |
| |
| public void update(Collection<RootInfo> roots) { |
| if (!Shared.isLauncherEnabled(mContext)) { |
| return; |
| } |
| |
| ShortcutManager mgr = mContext.getSystemService(ShortcutManager.class); |
| |
| Map<String, ShortcutInfo> existing = getPinnedShortcuts(mgr); |
| List<ShortcutInfo> devices = getDeviceShortcuts(roots); |
| List<String> deviceIds = new ArrayList<>(); |
| for (ShortcutInfo s : devices) { |
| deviceIds.add(s.getId()); |
| } |
| |
| mgr.setDynamicShortcuts(devices.subList(0, getNumDynSlots(mgr, devices.size()))); |
| |
| // Mark any shortcut that doesn't correspond to a current root as disabled. |
| List<String> disabled = new ArrayList<>(); |
| for (String id : existing.keySet()) { |
| // If it isn't in candidates, it isn't a live target, so we disable it. |
| if (!deviceIds.contains(id)) { |
| disabled.add(id); |
| } |
| } |
| |
| mgr.enableShortcuts(deviceIds); |
| mgr.disableShortcuts(disabled); |
| } |
| |
| /** |
| * Return at most four awesome devices/roots to include as dynamic shortcuts. |
| */ |
| private List<ShortcutInfo> getDeviceShortcuts(Collection<RootInfo> roots) { |
| List<ShortcutInfo> devices = new ArrayList<>(); |
| for (RootInfo root : roots) { |
| String id = root.getUri().toString(); |
| // TODO: Hook up third party providers. For now, there may be dupes when |
| // user has multiple accounts installed, and the plain title doesn't |
| // disambiguate for the user. So, we don't add them. |
| // if (!Providers.isSystemProvider(root.authority)) { |
| // // add third party providers at the beginning of the list. |
| // devices.add(createShortcut(root, R.drawable.ic_folder_shortcut)); |
| // } else |
| if (root.isAdvanced() && root.authority.equals(Providers.AUTHORITY_STORAGE)) { |
| // internal storage |
| devices.add(0, createShortcut(root, R.drawable.ic_advanced_shortcut)); |
| } else if (root.isAdvanced()) { |
| // probably just bugreports provider |
| devices.add(0, createShortcut(root, R.drawable.ic_folder_shortcut)); |
| } |
| // TODO: Hook up USB and MTP devices. In order to do this we need |
| // to fire up a broadcast to listen for ACTION_MEDIA_MOUNTED |
| // and ACTION_MEDIA_REMOVED. But doing so now would require a good |
| // bit of refactoring, rendering out of scope for now. <sadface>. |
| // else if (root.isUsb() || root.isMtp()) { |
| // // probably just bugreports provider |
| // devices.add(0, createShortcut(root, R.drawable.ic_usb_shortcut)); |
| // } |
| } |
| |
| return devices; |
| } |
| |
| private Map<String, ShortcutInfo> getPinnedShortcuts(ShortcutManager mgr) { |
| Map<String, ShortcutInfo> pinned = new HashMap<>(); |
| for (ShortcutInfo s : mgr.getDynamicShortcuts()) { |
| pinned.put(s.getId(), s); |
| } |
| return pinned; |
| } |
| |
| private int getNumDynSlots(ShortcutManager mgr, int numDevices) { |
| int slots = mgr.getMaxShortcutCountPerActivity() - mgr.getManifestShortcuts().size(); |
| return numDevices >= slots ? slots : numDevices; |
| } |
| |
| private ShortcutInfo createShortcut(RootInfo root, @DrawableRes int resId) { |
| Intent intent = new Intent(mContext, FilesActivity.class); |
| intent.setAction(Intent.ACTION_VIEW); |
| intent.setData(root.getUri()); |
| |
| return new ShortcutInfo.Builder(mContext, root.getUri().toString()) |
| .setShortLabel(root.title) |
| .setIcon(Icon.createWithResource(mContext, resId)) |
| .setIntent(intent) |
| .build(); |
| } |
| } |