1 /*
2  * Copyright (C) 2014 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.tv.settings.util;
18 
19 import android.content.ContentResolver;
20 import android.content.Context;
21 import android.content.Intent.ShortcutIconResource;
22 import android.content.res.Resources;
23 import android.net.Uri;
24 
25 /**
26  * Utilities for working with URIs.
27  */
28 public final class UriUtils {
29 
30     private static final String SCHEME_SHORTCUT_ICON_RESOURCE = "shortcut.icon.resource";
31     private static final String SCHEME_DELIMITER = "://";
32     private static final String URI_PATH_DELIMITER = "/";
33     private static final String URI_PACKAGE_DELIMITER = ":";
34     private static final String HTTP_PREFIX = "http";
35     private static final String HTTPS_PREFIX = "https";
36     private static final String SCHEME_ACCOUNT_IMAGE = "image.account";
37     private static final String ACCOUNT_IMAGE_CHANGE_NOTIFY_URI = "change_notify_uri";
38 
39     /**
40      * Non instantiable.
41      */
UriUtils()42     private UriUtils() {}
43 
44     /**
45      * get resource uri representation for a resource of a package
46      */
getAndroidResourceUri(Context context, int resourceId)47     public static String getAndroidResourceUri(Context context, int resourceId) {
48         return getAndroidResourceUri(context.getResources(), resourceId);
49     }
50 
51     /**
52      * get resource uri representation for a resource
53      */
getAndroidResourceUri(Resources resources, int resourceId)54     public static String getAndroidResourceUri(Resources resources, int resourceId) {
55         return ContentResolver.SCHEME_ANDROID_RESOURCE
56                 + SCHEME_DELIMITER + resources.getResourceName(resourceId)
57                         .replace(URI_PACKAGE_DELIMITER, URI_PATH_DELIMITER);
58     }
59 
60     /**
61      * Gets a URI with short cut icon scheme.
62      */
getShortcutIconResourceUri(ShortcutIconResource iconResource)63     public static Uri getShortcutIconResourceUri(ShortcutIconResource iconResource) {
64         return Uri.parse(SCHEME_SHORTCUT_ICON_RESOURCE + SCHEME_DELIMITER + iconResource.packageName
65                 + URI_PATH_DELIMITER
66                 + iconResource.resourceName.replace(URI_PACKAGE_DELIMITER, URI_PATH_DELIMITER));
67     }
68 
69     /**
70      * Checks if the URI refers to an Android resource.
71      */
isAndroidResourceUri(Uri uri)72     public static boolean isAndroidResourceUri(Uri uri) {
73         return ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme());
74     }
75 
76     /**
77      * Checks if the URI refers to an account image.
78      */
isAccountImageUri(Uri uri)79     public static boolean isAccountImageUri(Uri uri) {
80         return uri != null && SCHEME_ACCOUNT_IMAGE.equals(uri.getScheme());
81     }
82 
getAccountName(Uri uri)83     public static String getAccountName(Uri uri) {
84         if (isAccountImageUri(uri)) {
85             return uri.getAuthority() + uri.getPath();
86         } else {
87             throw new IllegalArgumentException("Invalid account image URI. " + uri);
88         }
89     }
90 
getAccountImageChangeNotifyUri(Uri uri)91     public static Uri getAccountImageChangeNotifyUri(Uri uri) {
92         if (isAccountImageUri(uri)) {
93             String notifyUri = uri.getQueryParameter(ACCOUNT_IMAGE_CHANGE_NOTIFY_URI);
94             if (notifyUri == null) {
95                 return null;
96             } else {
97                 return Uri.parse(notifyUri);
98             }
99         } else {
100             throw new IllegalArgumentException("Invalid account image URI. " + uri);
101         }
102     }
103 
104     /**
105      * Returns {@code true} if the URI refers to a content URI which can be opened via
106      * {@link ContentResolver#openInputStream(Uri)}.
107      */
isContentUri(Uri uri)108     public static boolean isContentUri(Uri uri) {
109         return ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) ||
110                 ContentResolver.SCHEME_FILE.equals(uri.getScheme());
111     }
112 
113     /**
114      * Checks if the URI refers to an shortcut icon resource.
115      */
isShortcutIconResourceUri(Uri uri)116     public static boolean isShortcutIconResourceUri(Uri uri) {
117         return SCHEME_SHORTCUT_ICON_RESOURCE.equals(uri.getScheme());
118     }
119 
120     /**
121      * Creates a shortcut icon resource object from an Android resource URI.
122      */
getIconResource(Uri uri)123     public static ShortcutIconResource getIconResource(Uri uri) {
124         if(isAndroidResourceUri(uri)) {
125             ShortcutIconResource iconResource = new ShortcutIconResource();
126             iconResource.packageName = uri.getAuthority();
127             // Trim off the scheme + 3 extra for "://", then replace the first "/" with a ":"
128             iconResource.resourceName = uri.toString().substring(
129                     ContentResolver.SCHEME_ANDROID_RESOURCE.length() + SCHEME_DELIMITER.length())
130                     .replaceFirst(URI_PATH_DELIMITER, URI_PACKAGE_DELIMITER);
131             return iconResource;
132         } else if(isShortcutIconResourceUri(uri)) {
133             ShortcutIconResource iconResource = new ShortcutIconResource();
134             iconResource.packageName = uri.getAuthority();
135             iconResource.resourceName = uri.toString().substring(
136                     SCHEME_SHORTCUT_ICON_RESOURCE.length() + SCHEME_DELIMITER.length()
137                     + iconResource.packageName.length() + URI_PATH_DELIMITER.length())
138                     .replaceFirst(URI_PATH_DELIMITER, URI_PACKAGE_DELIMITER);
139             return iconResource;
140         } else {
141             throw new IllegalArgumentException("Invalid resource URI. " + uri);
142         }
143     }
144 
145     /**
146      * Returns {@code true} if this is a web URI.
147      */
isWebUri(Uri resourceUri)148     public static boolean isWebUri(Uri resourceUri) {
149         String scheme = resourceUri.getScheme() == null ? null
150                 : resourceUri.getScheme().toLowerCase();
151         return HTTP_PREFIX.equals(scheme) || HTTPS_PREFIX.equals(scheme);
152     }
153 
154 }
155