• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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.ondevicepersonalization.services.download;
18 
19 import android.util.JsonReader;
20 
21 import com.android.ondevicepersonalization.services.data.vendor.VendorData;
22 
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.nio.charset.StandardCharsets;
27 import java.util.Base64;
28 import java.util.HashMap;
29 import java.util.Map;
30 
31 /**
32  * Parses the downloaded file.
33  */
34 class DownloadedFileParser {
parseJson(InputStream in)35     public static ParsedFileContents parseJson(InputStream in) throws IOException {
36         long syncToken = -1;
37         Map<String, VendorData> vendorDataMap = null;
38 
39         try (JsonReader reader = new JsonReader(new InputStreamReader(in))) {
40             reader.beginObject();
41             while (reader.hasNext()) {
42                 String name = reader.nextName();
43                 if (name.equals("syncToken")) {
44                     syncToken = reader.nextLong();
45                 } else if (name.equals("contents")) {
46                     vendorDataMap = readContentsArray(reader);
47                 } else {
48                     reader.skipValue();
49                 }
50             }
51             reader.endObject();
52         }
53         return new ParsedFileContents(syncToken, vendorDataMap);
54     }
55 
readContentsArray(JsonReader reader)56     private static Map<String, VendorData> readContentsArray(JsonReader reader)
57             throws IOException {
58         Map<String, VendorData> vendorDataMap = new HashMap<>();
59         reader.beginArray();
60         while (reader.hasNext()) {
61             VendorData data = readContent(reader);
62             if (data != null) {
63                 vendorDataMap.put(data.getKey(), data);
64             }
65         }
66         reader.endArray();
67 
68         return vendorDataMap;
69     }
70 
readContent(JsonReader reader)71     private static VendorData readContent(JsonReader reader) throws IOException {
72         String key = null;
73         byte[] data = null;
74         String encoding = null;
75         reader.beginObject();
76         while (reader.hasNext()) {
77             String name = reader.nextName();
78             if (name.equals("key")) {
79                 key = reader.nextString();
80             } else if (name.equals("data")) {
81                 data = reader.nextString().getBytes(StandardCharsets.UTF_8);
82             } else if (name.equals("encoding")) {
83                 encoding = reader.nextString();
84             } else {
85                 reader.skipValue();
86             }
87         }
88         reader.endObject();
89         if (key == null || data == null) {
90             return null;
91         }
92         if (encoding != null && !encoding.isBlank()) {
93             if (encoding.strip().equalsIgnoreCase("base64")) {
94                 data = Base64.getDecoder().decode(data);
95             } else if (!encoding.strip().equalsIgnoreCase("utf8")) {
96                 return null;
97             }
98         }
99         return new VendorData.Builder().setKey(key).setData(data).build();
100     }
101 
DownloadedFileParser()102     private DownloadedFileParser() {}
103 }
104