1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package android.slice.cts;
16 
17 import static java.util.stream.Collectors.toList;
18 
19 import android.app.PendingIntent;
20 import android.app.slice.Slice;
21 import android.app.slice.Slice.Builder;
22 import android.app.slice.SliceSpec;
23 import android.content.ContentResolver;
24 import android.content.Intent;
25 import android.graphics.drawable.Icon;
26 import android.net.Uri;
27 import android.os.Bundle;
28 import android.os.Parcel;
29 import android.os.Parcelable;
30 
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.Set;
35 
36 public class SliceProvider extends android.app.slice.SliceProvider {
37 
38     static final String[] PATHS = new String[]{
39             "/set_flag",
40             "/subslice",
41             "/text",
42             "/icon",
43             "/action",
44             "/int",
45             "/timestamp",
46             "/hints",
47             "/bundle",
48             "/spec",
49     };
50 
51     public static final String SPEC_TYPE = "android.cts.SliceType";
52     public static final int SPEC_REV = 4;
53 
54     public static final SliceSpec SPEC = new SliceSpec(SPEC_TYPE, SPEC_REV);
55 
56     @Override
onCreate()57     public boolean onCreate() {
58         return true;
59     }
60 
61     @Override
onGetSliceDescendants(Uri uri)62     public Collection<Uri> onGetSliceDescendants(Uri uri) {
63         if (uri.getPath().equals("/")) {
64             Uri.Builder builder = new Uri.Builder()
65                     .scheme(ContentResolver.SCHEME_CONTENT)
66                     .authority("android.slice.cts");
67             return Arrays.asList(PATHS).stream().map(s ->
68                     builder.path(s).build()).collect(toList());
69         }
70         return Collections.emptyList();
71     }
72 
73     @Override
onBindSlice(Uri sliceUri, Set<SliceSpec> supportedSpecs)74     public Slice onBindSlice(Uri sliceUri, Set<SliceSpec> supportedSpecs) {
75         switch (sliceUri.getPath()) {
76             case "/set_flag":
77                 SliceBindingTest.sFlag = true;
78                 break;
79             case "/subslice":
80                 Builder b = new Builder(sliceUri, SPEC);
81                 return b.addSubSlice(new Slice.Builder(b).build(), "subslice").build();
82             case "/text":
83                 return new Slice.Builder(sliceUri, SPEC).addText("Expected text", "text",
84                         Collections.emptyList()).build();
85             case "/icon":
86                 return new Slice.Builder(sliceUri, SPEC).addIcon(
87                         Icon.createWithResource(getContext(), R.drawable.size_48x48), "icon",
88                         Collections.emptyList()).build();
89             case "/action":
90                 Builder builder = new Builder(sliceUri, SPEC);
91                 Slice subSlice = new Slice.Builder(builder).build();
92                 PendingIntent broadcast = PendingIntent.getBroadcast(getContext(), 0,
93                         new Intent(getContext().getPackageName() + ".action"),
94                         PendingIntent.FLAG_IMMUTABLE);
95                 return builder.addAction(broadcast, subSlice, "action").build();
96             case "/int":
97                 return new Slice.Builder(sliceUri, SPEC).addInt(0xff121212, "int",
98                         Collections.emptyList()).build();
99             case "/timestamp":
100                 return new Slice.Builder(sliceUri, SPEC).addLong(43, "timestamp",
101                         Collections.emptyList()).build();
102             case "/hints":
103                 return new Slice.Builder(sliceUri, SPEC)
104                         .addHints(Arrays.asList(Slice.HINT_LIST))
105                         .addText("Text", null, Arrays.asList(Slice.HINT_TITLE))
106                         .addIcon(Icon.createWithResource(getContext(), R.drawable.size_48x48),
107                                 null, Arrays.asList(Slice.HINT_NO_TINT, Slice.HINT_LARGE))
108                         .build();
109             case "/bundle":
110                 Bundle b1 = new Bundle();
111                 b1.putParcelable("a", new TestParcel());
112                 return new Slice.Builder(sliceUri, SPEC).addBundle(b1, "bundle",
113                         Collections.emptyList()).build();
114             case "/spec":
115                 return new Slice.Builder(sliceUri, SPEC)
116                         .build();
117         }
118         return new Slice.Builder(sliceUri, SPEC).build();
119     }
120 
121     public static class TestParcel implements Parcelable {
122 
123         private final int mValue;
124 
TestParcel()125         public TestParcel() {
126             mValue = 42;
127         }
128 
TestParcel(Parcel in)129         protected TestParcel(Parcel in) {
130             mValue = in.readInt();
131         }
132 
133         @Override
writeToParcel(Parcel dest, int flags)134         public void writeToParcel(Parcel dest, int flags) {
135             dest.writeInt(mValue);
136         }
137 
138         @Override
describeContents()139         public int describeContents() {
140             return 0;
141         }
142 
143         @Override
equals(Object obj)144         public boolean equals(Object obj) {
145             try {
146                 TestParcel p = (TestParcel) obj;
147                 return p.mValue == mValue;
148             } catch (ClassCastException e) {
149                 return false;
150             }
151         }
152 
153         public static final Creator<TestParcel> CREATOR = new Creator<TestParcel>() {
154             @Override
155             public TestParcel createFromParcel(Parcel in) {
156                 return new TestParcel(in);
157             }
158 
159             @Override
160             public TestParcel[] newArray(int size) {
161                 return new TestParcel[size];
162             }
163         };
164     }
165 }
166