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