SliceXml.java revision 0f4ca634bbc43ddff900c35f7d2a43b55d8c830d
1901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk/* 2901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * Copyright 2017 The Android Open Source Project 3901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * 4901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 5901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * you may not use this file except in compliance with the License. 6901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * You may obtain a copy of the License at 7901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * 8901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 9901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * 10901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * Unless required by applicable law or agreed to in writing, software 11901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 12901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * See the License for the specific language governing permissions and 14901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * limitations under the License. 15901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk */ 16901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 1785ef1446b82c8783a50af92c4cb1389fe0d0e907Aurimas Liutikaspackage androidx.slice; 18901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 19901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport static org.xmlpull.v1.XmlPullParser.START_TAG; 20901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport static org.xmlpull.v1.XmlPullParser.TEXT; 21901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 22901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport android.annotation.SuppressLint; 23901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport android.content.Context; 24901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport android.graphics.Bitmap; 25901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport android.graphics.drawable.Drawable; 26901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport android.net.Uri; 27901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport android.text.Html; 28901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport android.text.Spanned; 29901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport android.text.TextUtils; 30901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 313ec422a2e2a46b51d4cc6926fcaa35caacbdf98dJason Monkimport androidx.annotation.RestrictTo; 323ec422a2e2a46b51d4cc6926fcaa35caacbdf98dJason Monkimport androidx.core.graphics.drawable.IconCompat; 333ec422a2e2a46b51d4cc6926fcaa35caacbdf98dJason Monk 34901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport org.xmlpull.v1.XmlPullParser; 35901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport org.xmlpull.v1.XmlPullParserException; 36901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport org.xmlpull.v1.XmlPullParserFactory; 37901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport org.xmlpull.v1.XmlSerializer; 38901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 39901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport java.io.IOException; 40901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport java.io.InputStream; 41901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport java.io.OutputStream; 42901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkimport java.util.List; 43901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 44901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk/** 45901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk * @hide 46901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk */ 47901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk@RestrictTo(RestrictTo.Scope.LIBRARY) 48901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monkclass SliceXml { 49901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 50901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static final String NAMESPACE = null; 51901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 52901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static final String TAG_SLICE = "slice"; 53901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static final String TAG_ITEM = "item"; 54901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 55901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static final String ATTR_URI = "uri"; 56901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static final String ATTR_FORMAT = "format"; 57901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static final String ATTR_SUBTYPE = "subtype"; 58901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static final String ATTR_HINTS = "hints"; 59901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 60901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk public static Slice parseSlice(InputStream input, String encoding) throws IOException { 61901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk try { 62901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); 63901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk parser.setInput(input, encoding); 64901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 65901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk int outerDepth = parser.getDepth(); 66901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk int type; 67901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk Slice s = null; 68901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 69901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 70901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (type != START_TAG) { 71901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk continue; 72901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 73901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk s = parseSlice(parser); 74901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 75901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk return s; 76901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } catch (XmlPullParserException e) { 77901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk throw new IOException("Unable to init XML Serialization", e); 78901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 79901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 80901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 81901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk @SuppressLint("WrongConstant") 82901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static Slice parseSlice(XmlPullParser parser) 83901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk throws IOException, XmlPullParserException { 84901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (!TAG_SLICE.equals(parser.getName())) { 85901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk throw new IOException("Unexpected tag " + parser.getName()); 86901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 87901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk int outerDepth = parser.getDepth(); 88901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk int type; 89901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String uri = parser.getAttributeValue(NAMESPACE, ATTR_URI); 90901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk Slice.Builder b = new Slice.Builder(Uri.parse(uri)); 91901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String[] hints = hints(parser.getAttributeValue(NAMESPACE, ATTR_HINTS)); 92901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk b.addHints(hints); 93901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 94901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 95901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 96901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (type == START_TAG && TAG_ITEM.equals(parser.getName())) { 97901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk parseItem(b, parser); 98901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 99901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 100901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk return b.build(); 101901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 102901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 103901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk @SuppressLint("WrongConstant") 104901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static void parseItem(Slice.Builder b, XmlPullParser parser) 105901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk throws IOException, XmlPullParserException { 106901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk int type; 107901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk int outerDepth = parser.getDepth(); 108901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String format = parser.getAttributeValue(NAMESPACE, ATTR_FORMAT); 109901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String subtype = parser.getAttributeValue(NAMESPACE, ATTR_SUBTYPE); 110901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String hintStr = parser.getAttributeValue(NAMESPACE, ATTR_HINTS); 111901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String[] hints = hints(hintStr); 112901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String v; 113901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 114901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 115901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (type == TEXT) { 116901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk switch (format) { 117901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_REMOTE_INPUT: 118901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk // Nothing for now. 119901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 120901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_IMAGE: 121901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk v = parser.getText(); 122901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (!TextUtils.isEmpty(v)) { 123901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (android.os.Build.VERSION.SDK_INT 124901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk >= android.os.Build.VERSION_CODES.M) { 125901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String[] split = v.split(","); 126901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk int w = Integer.parseInt(split[0]); 127901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk int h = Integer.parseInt(split[1]); 128901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk Bitmap image = Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8); 1293ec422a2e2a46b51d4cc6926fcaa35caacbdf98dJason Monk b.addIcon(IconCompat.createWithBitmap(image), subtype, hints); 130901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 131901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 132901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 133901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_INT: 134901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk v = parser.getText(); 135901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk b.addInt(Integer.parseInt(v), subtype, hints); 136901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 137901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_TEXT: 138901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk v = parser.getText(); 139901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk b.addText(Html.fromHtml(v), subtype, hints); 140901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 141901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_TIMESTAMP: 142901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk v = parser.getText(); 143901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk b.addTimestamp(Long.parseLong(v), subtype, hints); 144901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 145901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk default: 146901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk throw new IllegalArgumentException("Unrecognized format " + format); 147901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 148901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } else if (type == START_TAG && TAG_SLICE.equals(parser.getName())) { 149901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk b.addSubSlice(parseSlice(parser), subtype); 150901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 151901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 152901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 153901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 154901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static String[] hints(String hintStr) { 155901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk return TextUtils.isEmpty(hintStr) ? new String[0] : hintStr.split(","); 156901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 157901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 158901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk public static void serializeSlice(Slice s, Context context, OutputStream output, 159901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String encoding, SliceUtils.SerializeOptions options) throws IOException { 160901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk try { 161901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer(); 162901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.setOutput(output, encoding); 163901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.startDocument(encoding, null); 164901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 165901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serialize(s, context, options, serializer); 166901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 167901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.endDocument(); 168901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.flush(); 169901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } catch (XmlPullParserException e) { 170901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk throw new IOException("Unable to init XML Serialization", e); 171901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 172901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 173901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 174901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static void serialize(Slice s, Context context, SliceUtils.SerializeOptions options, 175901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk XmlSerializer serializer) throws IOException { 176901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.startTag(NAMESPACE, TAG_SLICE); 177901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.attribute(NAMESPACE, ATTR_URI, s.getUri().toString()); 178901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (!s.getHints().isEmpty()) { 179901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.attribute(NAMESPACE, ATTR_HINTS, hintStr(s.getHints())); 180901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 181901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk for (SliceItem item : s.getItems()) { 182901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serialize(item, context, options, serializer); 183901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 184901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 185901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.endTag(NAMESPACE, TAG_SLICE); 186901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 187901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 188901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static void serialize(SliceItem item, Context context, 189901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk SliceUtils.SerializeOptions options, XmlSerializer serializer) throws IOException { 190901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk String format = item.getFormat(); 191901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk options.checkThrow(format); 192901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 193901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.startTag(NAMESPACE, TAG_ITEM); 194901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.attribute(NAMESPACE, ATTR_FORMAT, format); 195901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (item.getSubType() != null) { 196901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.attribute(NAMESPACE, ATTR_SUBTYPE, item.getSubType()); 197901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 198901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (!item.getHints().isEmpty()) { 199901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.attribute(NAMESPACE, ATTR_HINTS, hintStr(item.getHints())); 200901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 201901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 202901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk switch (format) { 203901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_ACTION: 204901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (options.getActionMode() == SliceUtils.SerializeOptions.MODE_DISABLE) { 205901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serialize(item.getSlice(), context, options, serializer); 206901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 207901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 208901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_REMOTE_INPUT: 209901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk // Nothing for now. 210901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 211901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_IMAGE: 212901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (options.getImageMode() == SliceUtils.SerializeOptions.MODE_DISABLE) { 213901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { 214901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk Drawable d = item.getIcon().loadDrawable(context); 215901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.text(String.format("%d,%d", 216901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk d.getIntrinsicWidth(), d.getIntrinsicHeight())); 217901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 218901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 219901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 220901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_INT: 221901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.text(String.valueOf(item.getInt())); 222901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 223901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_SLICE: 224901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serialize(item.getSlice(), context, options, serializer); 225901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 226901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_TEXT: 227901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk if (item.getText() instanceof Spanned) { 228901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.text(Html.toHtml((Spanned) item.getText())); 229901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } else { 230901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.text(String.valueOf(item.getText())); 231901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 232901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 233901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk case android.app.slice.SliceItem.FORMAT_TIMESTAMP: 234901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.text(String.valueOf(item.getTimestamp())); 235901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk break; 236901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk default: 237901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk throw new IllegalArgumentException("Unrecognized format " + format); 238901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 239901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk serializer.endTag(NAMESPACE, TAG_ITEM); 240901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 241901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk 242901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk private static String hintStr(List<String> hints) { 243901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk return TextUtils.join(",", hints); 244901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk } 2450f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton 2460f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton private SliceXml() { 2470f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton } 248901e2a634a8fce0c5e5acaa369e4e69326980b96Jason Monk} 249