1 /* 2 * Copyright (C) 2022 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 android.service.ambientcontext; 18 19 import android.annotation.NonNull; 20 import android.annotation.SuppressLint; 21 import android.annotation.SystemApi; 22 import android.app.ambientcontext.AmbientContextEvent; 23 import android.os.Parcelable; 24 25 import com.android.internal.util.AnnotationValidations; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 import java.util.Objects; 30 31 /** 32 * Represents a {@code AmbientContextEvent} detection result reported by the detection service. 33 * 34 * @hide 35 */ 36 @SystemApi 37 public final class AmbientContextDetectionResult implements Parcelable { 38 39 /** 40 * The bundle key for this class of object, used in {@code RemoteCallback#sendResult}. 41 * 42 * @hide 43 */ 44 public static final String RESULT_RESPONSE_BUNDLE_KEY = 45 "android.app.ambientcontext.AmbientContextDetectionResultBundleKey"; 46 @NonNull private final List<AmbientContextEvent> mEvents; 47 @NonNull private final String mPackageName; 48 AmbientContextDetectionResult( @onNull List<AmbientContextEvent> events, @NonNull String packageName)49 AmbientContextDetectionResult( 50 @NonNull List<AmbientContextEvent> events, 51 @NonNull String packageName) { 52 this.mEvents = events; 53 AnnotationValidations.validate(NonNull.class, null, mEvents); 54 this.mPackageName = packageName; 55 AnnotationValidations.validate(NonNull.class, null, mPackageName); 56 } 57 58 /** 59 * A list of detected event. 60 */ 61 @SuppressLint("ConcreteCollection") getEvents()62 public @NonNull List<AmbientContextEvent> getEvents() { 63 return mEvents; 64 } 65 66 /** 67 * The package to deliver the response to. 68 */ getPackageName()69 public @NonNull String getPackageName() { 70 return mPackageName; 71 } 72 73 @Override toString()74 public String toString() { 75 return "AmbientContextEventResponse { " 76 + "events = " + mEvents + ", " + "packageName = " + mPackageName + " }"; 77 } 78 79 @Override writeToParcel(@onNull android.os.Parcel dest, int flags)80 public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { 81 byte flg = 0; 82 dest.writeByte(flg); 83 dest.writeParcelableList(mEvents, flags); 84 dest.writeString(mPackageName); 85 } 86 87 @Override describeContents()88 public int describeContents() { 89 return 0; 90 } 91 92 /** @hide */ 93 @SuppressWarnings({"unchecked", "RedundantCast"}) AmbientContextDetectionResult(@onNull android.os.Parcel in)94 AmbientContextDetectionResult(@NonNull android.os.Parcel in) { 95 byte flg = in.readByte(); 96 ArrayList<AmbientContextEvent> events = new ArrayList<>(); 97 in.readParcelableList(events, AmbientContextEvent.class.getClassLoader(), 98 AmbientContextEvent.class); 99 String packageName = in.readString(); 100 101 this.mEvents = events; 102 AnnotationValidations.validate( 103 NonNull.class, null, mEvents); 104 this.mPackageName = packageName; 105 AnnotationValidations.validate( 106 NonNull.class, null, mPackageName); 107 } 108 109 public static final @NonNull Creator<AmbientContextDetectionResult> CREATOR = 110 new Creator<AmbientContextDetectionResult>() { 111 @Override 112 public AmbientContextDetectionResult[] newArray(int size) { 113 return new AmbientContextDetectionResult[size]; 114 } 115 116 @Override 117 public AmbientContextDetectionResult createFromParcel(@NonNull android.os.Parcel in) { 118 return new AmbientContextDetectionResult(in); 119 } 120 }; 121 122 /** 123 * A builder for {@link AmbientContextDetectionResult} 124 */ 125 @SuppressWarnings("WeakerAccess") 126 public static final class Builder { 127 private @NonNull ArrayList<AmbientContextEvent> mEvents; 128 private @NonNull String mPackageName; 129 private long mBuilderFieldsSet = 0L; 130 Builder(@onNull String packageName)131 public Builder(@NonNull String packageName) { 132 Objects.requireNonNull(packageName); 133 mPackageName = packageName; 134 } 135 136 /** 137 * Adds an event to the builder. 138 */ addEvent(@onNull AmbientContextEvent value)139 public @NonNull Builder addEvent(@NonNull AmbientContextEvent value) { 140 checkNotUsed(); 141 if (mEvents == null) { 142 mBuilderFieldsSet |= 0x1; 143 mEvents = new ArrayList<>(); 144 } 145 mEvents.add(value); 146 return this; 147 } 148 149 /** 150 * Adds a list of events to the builder. 151 */ addEvents(@onNull List<AmbientContextEvent> values)152 public @NonNull Builder addEvents(@NonNull List<AmbientContextEvent> values) { 153 checkNotUsed(); 154 if (mEvents == null) { 155 mBuilderFieldsSet |= 0x1; 156 mEvents = new ArrayList<>(); 157 } 158 mEvents.addAll(values); 159 return this; 160 } 161 162 /** 163 * Clears all events from the builder. 164 */ clearEvents()165 public @NonNull Builder clearEvents() { 166 checkNotUsed(); 167 if (mEvents != null) { 168 mEvents.clear(); 169 } 170 return this; 171 } 172 173 /** Builds the instance. This builder should not be touched after calling this! */ build()174 public @NonNull AmbientContextDetectionResult build() { 175 checkNotUsed(); 176 mBuilderFieldsSet |= 0x2; // Mark builder used 177 178 if ((mBuilderFieldsSet & 0x1) == 0) { 179 mEvents = new ArrayList<>(); 180 } 181 AmbientContextDetectionResult o = new AmbientContextDetectionResult( 182 mEvents, 183 mPackageName); 184 return o; 185 } 186 checkNotUsed()187 private void checkNotUsed() { 188 if ((mBuilderFieldsSet & 0x2) != 0) { 189 throw new IllegalStateException( 190 "This Builder should not be reused. Use a new Builder instance instead"); 191 } 192 } 193 } 194 } 195