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.systemui.media.controls.util; 18 19 import android.annotation.Nullable; 20 import android.content.Context; 21 import android.content.pm.ApplicationInfo; 22 import android.content.pm.PackageManager; 23 import android.os.Bundle; 24 import android.text.TextUtils; 25 import android.util.Pair; 26 27 import androidx.core.math.MathUtils; 28 import androidx.media.utils.MediaConstants; 29 30 /** 31 * Utility class with common methods for media controls 32 */ 33 public class MediaDataUtils { 34 35 /** 36 * Get the application label for a given package 37 * @param context the context to use 38 * @param packageName Package to check 39 * @param unknownName Fallback string if application is not found 40 * @return The label or fallback string 41 */ getAppLabel(Context context, String packageName, String unknownName)42 public static String getAppLabel(Context context, String packageName, String unknownName) { 43 if (TextUtils.isEmpty(packageName)) { 44 return null; 45 } 46 final PackageManager packageManager = context.getPackageManager(); 47 ApplicationInfo applicationInfo; 48 try { 49 applicationInfo = packageManager.getApplicationInfo(packageName, 0); 50 } catch (PackageManager.NameNotFoundException e) { 51 applicationInfo = null; 52 } 53 final String applicationName = 54 (String) (applicationInfo != null 55 ? packageManager.getApplicationLabel(applicationInfo) 56 : unknownName); 57 return applicationName; 58 } 59 60 /** 61 * Check the bundle for extras indicating the progress percentage 62 * 63 * @param extras 64 * @return the progress value between 0-1 inclusive if prsent, otherwise null 65 */ getDescriptionProgress(@ullable Bundle extras)66 public static Double getDescriptionProgress(@Nullable Bundle extras) { 67 if (extras == null 68 || !extras.containsKey(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS)) { 69 return null; 70 } 71 72 int status = extras.getInt(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS); 73 switch (status) { 74 case MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_NOT_PLAYED: 75 return 0.0; 76 case MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_FULLY_PLAYED: 77 return 1.0; 78 case MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED: { 79 if (extras 80 .containsKey(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE)) { 81 double percent = extras 82 .getDouble(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE); 83 return MathUtils.clamp(percent, 0.0, 1.0); 84 } else { 85 return 0.5; 86 } 87 } 88 } 89 return null; 90 } 91 92 /** 93 * Calculate a scale factor that will allow the input to fill the target size. 94 * 95 * @param input width, height of the input view 96 * @param target width, height of the target view 97 * @return the scale factor; 0 if any given dimension is 0 98 */ getScaleFactor(Pair<Integer, Integer> input, Pair<Integer, Integer> target)99 public static float getScaleFactor(Pair<Integer, Integer> input, 100 Pair<Integer, Integer> target) { 101 float width = (float) input.first; 102 float height = (float) input.second; 103 104 float targetWidth = (float) target.first; 105 float targetHeight = (float) target.second; 106 107 if (width == 0 || height == 0 || targetWidth == 0 || targetHeight == 0) { 108 return 0f; 109 } 110 111 if ((width / height) > (targetWidth / targetHeight)) { 112 // Input is wider than target view, scale to match height 113 return targetHeight / height; 114 } else { 115 // Input is taller than target view, scale to match width 116 return targetWidth / width; 117 } 118 } 119 } 120