1 /* 2 * Copyright (C) 2022 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 17 package com.android.providers.media.photopicker.util; 18 19 import static com.android.providers.media.util.MimeUtils.isImageMimeType; 20 import static com.android.providers.media.util.MimeUtils.isVideoMimeType; 21 22 import android.content.Intent; 23 24 import androidx.annotation.Nullable; 25 26 /** 27 * Utility class for various mime filter checks. 28 */ 29 public class MimeFilterUtils { 30 31 /** 32 * Checks if mime type filters set via {@link Intent#setType(String)} and 33 * {@link Intent#EXTRA_MIME_TYPES} on the intent requires more than media items. 34 * 35 * Note: TODO(b/224756380): Returns true if there are more than 1 mime type filters. 36 * 37 * @param intent the intent to check mimeType filters of 38 */ requiresUnsupportedFilters(Intent intent)39 public static boolean requiresUnsupportedFilters(Intent intent) { 40 // EXTRA_MIME_TYPES has higher priority over getType() filter. 41 if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) { 42 return requiresUnsupportedFilters(intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES)); 43 } 44 45 // GET_CONTENT intent filter catches "images/*", "video/*" and "*/*" mimeTypes only 46 // No need to check for other types like "audio/*" etc as they never reach PhotoPicker 47 return intent.getType().equals("*/*"); 48 } 49 50 /** 51 * Checks if the given string is an image or video mime type 52 */ isMimeTypeMedia(@ullable String mimeType)53 public static boolean isMimeTypeMedia(@Nullable String mimeType) { 54 return isImageMimeType(mimeType) || isVideoMimeType(mimeType); 55 } 56 57 /** 58 * Extracts relevant mime type filter for the given intent 59 */ getMimeTypeFilters(Intent intent)60 public static String[] getMimeTypeFilters(Intent intent) throws IllegalArgumentException { 61 // EXTRA_MIME_TYPES has higher priority over getType() filter. 62 if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) { 63 final String[] extraMimeTypes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES); 64 65 if (requiresUnsupportedFilters(extraMimeTypes)) { 66 if (Intent.ACTION_GET_CONTENT.equals(intent.getAction())) { 67 // This is a special case in which PhotoPicker is explicitly opened from 68 // DocumentsUI as it is seen as one of the options. In this show all images 69 // and videos. 70 // If this was not a special case, then the picker would close itself and 71 // redirect the request to DocumentsUI before hitting this point. 72 return null; 73 } 74 75 throw new IllegalArgumentException("Invalid EXTRA_MIME_TYPES value, only media " 76 + "mime type filters are accepted"); 77 } 78 79 return extraMimeTypes; 80 } 81 82 final String mimeType = intent.getType(); 83 if (MimeFilterUtils.isMimeTypeMedia(mimeType)) { 84 return new String[] { mimeType }; 85 } 86 87 return null; 88 } 89 requiresUnsupportedFilters(String[] mimeTypeFilters)90 private static boolean requiresUnsupportedFilters(String[] mimeTypeFilters) { 91 // no filters imply that we should show non-media files as well 92 if (mimeTypeFilters == null || mimeTypeFilters.length == 0) { 93 return true; 94 } 95 96 for (String mimeTypeFilter : mimeTypeFilters) { 97 if (!isMimeTypeMedia(mimeTypeFilter)) { 98 return true; 99 } 100 } 101 102 return false; 103 } 104 } 105