1 /*
2  * Copyright (C) 2020 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.playlist;
18 
19 import android.content.ContentResolver;
20 import android.net.Uri;
21 
22 import androidx.annotation.NonNull;
23 
24 import com.android.providers.media.util.MimeUtils;
25 
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.nio.file.Path;
31 import java.util.List;
32 import java.util.Locale;
33 
34 /**
35  * Interface that knows how to {@link #read} and {@link #write} a set of
36  * playlist items using a specific file format. This design allows you to easily
37  * convert between playlist file formats by reading one format and writing to
38  * another.
39  */
40 public interface PlaylistPersister {
read(@onNull InputStream in, @NonNull List<Path> items)41     public void read(@NonNull InputStream in, @NonNull List<Path> items) throws IOException;
write(@onNull OutputStream out, @NonNull List<Path> items)42     public void write(@NonNull OutputStream out, @NonNull List<Path> items) throws IOException;
43 
44     /**
45      * Resolve a concrete version of this interface which matches the given
46      * playlist file format.
47      */
resolvePersister(@onNull File file)48     public static @NonNull PlaylistPersister resolvePersister(@NonNull File file)
49             throws IOException {
50         return resolvePersister(MimeUtils.resolveMimeType(file));
51     }
52 
53     /**
54      * Resolve a concrete version of this interface which matches the given
55      * playlist file format.
56      */
resolvePersister(@onNull ContentResolver resolver, @NonNull Uri uri)57     public static @NonNull PlaylistPersister resolvePersister(@NonNull ContentResolver resolver,
58             @NonNull Uri uri) throws IOException {
59         return resolvePersister(resolver.getType(uri));
60     }
61 
62     /**
63      * Resolve a concrete version of this interface which matches the given
64      * playlist file format.
65      */
resolvePersister(@onNull String mimeType)66     public static @NonNull PlaylistPersister resolvePersister(@NonNull String mimeType)
67             throws IOException {
68         switch (mimeType.toLowerCase(Locale.ROOT)) {
69             case "audio/mpegurl":
70             case "audio/x-mpegurl":
71             case "application/vnd.apple.mpegurl":
72             case "application/x-mpegurl":
73                 return new M3uPlaylistPersister();
74             case "audio/x-scpls":
75                 return new PlsPlaylistPersister();
76             case "application/vnd.ms-wpl":
77             case "video/x-ms-asf":
78                 return new WplPlaylistPersister();
79             case "application/xspf+xml":
80                 return new XspfPlaylistPersister();
81             default:
82                 throw new IOException("Unsupported playlist format " + mimeType);
83         }
84     }
85 }
86