1 /*
2  * Copyright (C) 2019 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.util;
18 
19 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
21 
22 import static com.android.providers.media.util.Logging.TAG;
23 
24 import android.content.Context;
25 import android.content.res.Resources;
26 import android.content.res.Resources.NotFoundException;
27 import android.icu.text.MessageFormat;
28 import android.util.Log;
29 
30 import androidx.annotation.NonNull;
31 import androidx.annotation.Nullable;
32 
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.HashMap;
36 import java.util.List;
37 import java.util.Locale;
38 import java.util.Map;
39 import java.util.Objects;
40 
41 public class StringUtils {
42 
43   /**
44    * Returns the formatted ICU format string corresponding to the provided resource ID and count
45    * number of entities in the plural string.
46    */
getICUFormatString(Resources resources, int count, int resourceID)47   public static String getICUFormatString(Resources resources, int count, int resourceID) {
48     MessageFormat msgFormat = new MessageFormat(
49         resources.getString(resourceID),
50         Locale.getDefault());
51     Map<String, Object> arguments = new HashMap<>();
52     arguments.put("count", count);
53     return msgFormat.format(arguments);
54   }
55 
getStringConfig(Context context, int resId)56   public static String getStringConfig(Context context, int resId) {
57       final Resources res = context.getResources();
58       try {
59           return res.getString(resId);
60       } catch (NotFoundException e) {
61           return null;
62       }
63   }
64 
65   /**
66    * Variant of {@link String#startsWith(String)} but which tests with
67    * case-insensitivity.
68    */
startsWithIgnoreCase(@ullable String target, @Nullable String other)69   public static boolean startsWithIgnoreCase(@Nullable String target, @Nullable String other) {
70     if (target == null || other == null) return false;
71     if (other.length() > target.length()) return false;
72     return target.regionMatches(true, 0, other, 0, other.length());
73   }
74 
75   /**
76    * Variant of {@link Objects#equal(Object, Object)} but which tests with
77    * case-insensitivity.
78    */
equalIgnoreCase(@ullable String a, @Nullable String b)79   public static boolean equalIgnoreCase(@Nullable String a, @Nullable String b) {
80       return (a != null) && a.equalsIgnoreCase(b);
81   }
82 
83   /**
84    * Returns a string array config as a {@code List<String>}.
85    */
getStringArrayConfig(Context context, int resId)86   public static List<String> getStringArrayConfig(Context context, int resId) {
87       final Resources res = context.getResources();
88       try {
89           final String[] configValue = res.getStringArray(resId);
90           return Arrays.asList(configValue);
91       } catch (NotFoundException e) {
92           return new ArrayList<String>();
93       }
94   }
95 
96   /**
97    * Returns the list of uncached relative paths after removing invalid ones.
98    */
verifySupportedUncachedRelativePaths(List<String> unverifiedPaths)99   public static List<String> verifySupportedUncachedRelativePaths(List<String> unverifiedPaths) {
100       final List<String> verifiedPaths = new ArrayList<>();
101       for (final String path : unverifiedPaths) {
102           if (path == null) {
103               continue;
104           }
105           if (path.startsWith("/")) {
106               Log.w(TAG, "Relative path config must not start with '/'. Ignoring: " + path);
107               continue;
108           }
109           if (!path.endsWith("/")) {
110               Log.w(TAG, "Relative path config must end with '/'. Ignoring: " + path);
111               continue;
112           }
113 
114           verifiedPaths.add(path);
115       }
116 
117       return verifiedPaths;
118   }
119 
120     /**
121      * Returns string description of {@link PackageManager}-s component state.
122      */
123     @NonNull
componentStateToString(int componentState)124     public static String componentStateToString(int componentState) {
125         final String componentStateAsString;
126         switch (componentState) {
127             case COMPONENT_ENABLED_STATE_DISABLED:
128                 componentStateAsString = "STATE_DISABLED";
129                 break;
130             case COMPONENT_ENABLED_STATE_ENABLED:
131                 componentStateAsString = "STATE_ENABLED";
132                 break;
133             default:
134                 componentStateAsString = "Unknown";
135                 break;
136         }
137         return String.format("%s ( %d )", componentStateAsString, componentState);
138     }
139 
140     /**
141      * Returns true if dateExpires is empty string or has null value.
142      */
isNullOrEmpty(String dateExpires)143     public static boolean isNullOrEmpty(String dateExpires) {
144         return dateExpires == null || dateExpires.trim().isEmpty()
145                 || dateExpires.trim().equalsIgnoreCase("null");
146     }
147 }
148