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 static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
20 import static org.xmlpull.v1.XmlPullParser.START_TAG;
21 
22 import android.util.Xml;
23 
24 import androidx.annotation.NonNull;
25 
26 import org.xmlpull.v1.XmlPullParser;
27 import org.xmlpull.v1.XmlPullParserException;
28 import org.xmlpull.v1.XmlSerializer;
29 
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.nio.charset.StandardCharsets;
34 import java.nio.file.FileSystem;
35 import java.nio.file.FileSystems;
36 import java.nio.file.Path;
37 import java.util.List;
38 
39 public class WplPlaylistPersister implements PlaylistPersister {
40     private static final String TAG_SMIL = "smil";
41     private static final String TAG_BODY = "body";
42     private static final String TAG_SEQ = "seq";
43     private static final String TAG_MEDIA = "media";
44 
45     private static final String ATTR_SRC = "src";
46 
47     @Override
read(@onNull InputStream in, @NonNull List<Path> items)48     public void read(@NonNull InputStream in, @NonNull List<Path> items) throws IOException {
49         final FileSystem fs = FileSystems.getDefault();
50         try {
51             final XmlPullParser parser = Xml.newPullParser();
52             parser.setInput(in, StandardCharsets.UTF_8.name());
53 
54             int type;
55             while ((type = parser.next()) != END_DOCUMENT) {
56                 if (type != START_TAG) continue;
57 
58                 if (TAG_MEDIA.equals(parser.getName())) {
59                     final String src = parser.getAttributeValue(null, ATTR_SRC);
60                     if (src != null) {
61                         items.add(fs.getPath(src.replace('\\', '/')));
62                     }
63                 }
64             }
65         } catch (XmlPullParserException e) {
66             throw new IOException(e);
67         }
68     }
69 
70     @Override
write(@onNull OutputStream out, @NonNull List<Path> items)71     public void write(@NonNull OutputStream out, @NonNull List<Path> items) throws IOException {
72         final XmlSerializer doc = Xml.newSerializer();
73         doc.setOutput(out, StandardCharsets.UTF_8.name());
74         doc.startDocument(null, true);
75         doc.startTag(null, TAG_SMIL);
76         doc.startTag(null, TAG_BODY);
77         doc.startTag(null, TAG_SEQ);
78         for (Path item : items) {
79             doc.startTag(null, TAG_MEDIA);
80             doc.attribute(null, ATTR_SRC, item.toString());
81             doc.endTag(null, TAG_MEDIA);
82         }
83         doc.endTag(null, TAG_SEQ);
84         doc.endTag(null, TAG_BODY);
85         doc.endTag(null, TAG_SMIL);
86         doc.endDocument();
87     }
88 }
89