1 /* 2 * Copyright (C) 2020 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.location; 18 19 import static android.Manifest.permission.LOCATION_BYPASS; 20 21 import android.Manifest; 22 import android.annotation.NonNull; 23 import android.annotation.RequiresFeature; 24 import android.annotation.RequiresPermission; 25 import android.annotation.SystemApi; 26 import android.content.pm.PackageManager; 27 import android.os.Parcel; 28 import android.os.Parcelable; 29 30 import java.util.Objects; 31 32 /** 33 * An encapsulation of various parameters for requesting last location via {@link LocationManager}. 34 * 35 * @hide 36 */ 37 @SystemApi 38 public final class LastLocationRequest implements Parcelable { 39 40 private final boolean mHiddenFromAppOps; 41 private final boolean mAdasGnssBypass; 42 private final boolean mLocationSettingsIgnored; 43 LastLocationRequest( boolean hiddenFromAppOps, boolean adasGnssBypass, boolean locationSettingsIgnored)44 private LastLocationRequest( 45 boolean hiddenFromAppOps, 46 boolean adasGnssBypass, 47 boolean locationSettingsIgnored) { 48 mHiddenFromAppOps = hiddenFromAppOps; 49 mAdasGnssBypass = adasGnssBypass; 50 mLocationSettingsIgnored = locationSettingsIgnored; 51 } 52 53 /** 54 * Returns true if this last location request should be ignored while updating app ops with 55 * location usage. This implies that someone else (usually the creator of the last location 56 * request) is responsible for updating app ops. 57 * 58 * @return true if this request should be ignored while updating app ops with location usage 59 * 60 * @hide 61 */ 62 @SystemApi isHiddenFromAppOps()63 public boolean isHiddenFromAppOps() { 64 return mHiddenFromAppOps; 65 } 66 67 /** 68 * Returns true if this request may access GNSS even if location settings would normally deny 69 * this, in order to enable automotive safety features. This field is only respected on 70 * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced 71 * Driving Assistance Systems) application. 72 * 73 * @return true if all limiting factors will be ignored to satisfy GNSS request 74 * 75 * @hide 76 */ 77 @SystemApi isAdasGnssBypass()78 public boolean isAdasGnssBypass() { 79 return mAdasGnssBypass; 80 } 81 82 83 /** 84 * Returns true if location settings, throttling, background location limits, and any other 85 * possible limiting factors will be ignored in order to satisfy this last location request. 86 * 87 * @return true if all limiting factors will be ignored to satisfy this request 88 * 89 * @hide 90 */ 91 @SystemApi isLocationSettingsIgnored()92 public boolean isLocationSettingsIgnored() { 93 return mLocationSettingsIgnored; 94 } 95 96 /** 97 * Returns true if any bypass flag is set on this request. For internal use only. 98 * 99 * @hide 100 */ isBypass()101 public boolean isBypass() { 102 return mAdasGnssBypass || mLocationSettingsIgnored; 103 } 104 105 public static final @NonNull Parcelable.Creator<LastLocationRequest> CREATOR = 106 new Parcelable.Creator<LastLocationRequest>() { 107 @Override 108 public LastLocationRequest createFromParcel(Parcel in) { 109 return new LastLocationRequest( 110 /* hiddenFromAppOps= */ in.readBoolean(), 111 /* adasGnssBypass= */ in.readBoolean(), 112 /* locationSettingsIgnored= */ in.readBoolean()); 113 } 114 @Override 115 public LastLocationRequest[] newArray(int size) { 116 return new LastLocationRequest[size]; 117 } 118 }; 119 @Override describeContents()120 public int describeContents() { 121 return 0; 122 } 123 124 @Override writeToParcel(@onNull Parcel parcel, int flags)125 public void writeToParcel(@NonNull Parcel parcel, int flags) { 126 parcel.writeBoolean(mHiddenFromAppOps); 127 parcel.writeBoolean(mAdasGnssBypass); 128 parcel.writeBoolean(mLocationSettingsIgnored); 129 } 130 131 @Override equals(Object o)132 public boolean equals(Object o) { 133 if (this == o) { 134 return true; 135 } 136 if (o == null || getClass() != o.getClass()) { 137 return false; 138 } 139 LastLocationRequest that = (LastLocationRequest) o; 140 return mHiddenFromAppOps == that.mHiddenFromAppOps 141 && mAdasGnssBypass == that.mAdasGnssBypass 142 && mLocationSettingsIgnored == that.mLocationSettingsIgnored; 143 } 144 145 @Override hashCode()146 public int hashCode() { 147 return Objects.hash(mHiddenFromAppOps, mAdasGnssBypass, mLocationSettingsIgnored); 148 } 149 150 @NonNull 151 @Override toString()152 public String toString() { 153 StringBuilder s = new StringBuilder(); 154 s.append("LastLocationRequest["); 155 if (mHiddenFromAppOps) { 156 s.append("hiddenFromAppOps, "); 157 } 158 if (mAdasGnssBypass) { 159 s.append("adasGnssBypass, "); 160 } 161 if (mLocationSettingsIgnored) { 162 s.append("settingsBypass, "); 163 } 164 if (s.length() > "LastLocationRequest[".length()) { 165 s.setLength(s.length() - 2); 166 } 167 s.append(']'); 168 return s.toString(); 169 } 170 171 /** 172 * A builder class for {@link LastLocationRequest}. 173 */ 174 public static final class Builder { 175 176 private boolean mHiddenFromAppOps; 177 private boolean mAdasGnssBypass; 178 private boolean mLocationSettingsIgnored; 179 180 /** 181 * Creates a new Builder. 182 */ Builder()183 public Builder() { 184 mHiddenFromAppOps = false; 185 mAdasGnssBypass = false; 186 mLocationSettingsIgnored = false; 187 } 188 189 /** 190 * Creates a new Builder with all parameters copied from the given last location request. 191 */ Builder(@onNull LastLocationRequest lastLocationRequest)192 public Builder(@NonNull LastLocationRequest lastLocationRequest) { 193 mHiddenFromAppOps = lastLocationRequest.mHiddenFromAppOps; 194 mAdasGnssBypass = lastLocationRequest.mAdasGnssBypass; 195 mLocationSettingsIgnored = lastLocationRequest.mLocationSettingsIgnored; 196 } 197 198 /** 199 * If set to true, indicates that app ops should not be updated with location usage due to 200 * this request. This implies that someone else (usually the creator of the last location 201 * request) is responsible for updating app ops as appropriate. Defaults to false. 202 * 203 * <p>Permissions enforcement occurs when resulting last location request is actually used, 204 * not when this method is invoked. 205 * 206 * @hide 207 */ 208 @SystemApi 209 @RequiresPermission(Manifest.permission.UPDATE_APP_OPS_STATS) setHiddenFromAppOps(boolean hiddenFromAppOps)210 public @NonNull Builder setHiddenFromAppOps(boolean hiddenFromAppOps) { 211 mHiddenFromAppOps = hiddenFromAppOps; 212 return this; 213 } 214 215 /** 216 * If set to true, indicates that the client is an ADAS (Advanced Driving Assistance 217 * Systems) client, which requires access to GNSS even if location settings would normally 218 * deny this, in order to enable auto safety features. This field is only respected on 219 * automotive devices, and only if the client is recognized as a legitimate ADAS 220 * application. Defaults to false. 221 * 222 * <p>Permissions enforcement occurs when resulting location request is actually used, not 223 * when this method is invoked. 224 * 225 * @hide 226 */ 227 @SystemApi 228 @RequiresPermission(LOCATION_BYPASS) 229 @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) setAdasGnssBypass(boolean adasGnssBypass)230 public @NonNull LastLocationRequest.Builder setAdasGnssBypass(boolean adasGnssBypass) { 231 mAdasGnssBypass = adasGnssBypass; 232 return this; 233 } 234 235 /** 236 * If set to true, indicates that location settings, throttling, background location limits, 237 * and any other possible limiting factors should be ignored in order to satisfy this 238 * last location request. This is only intended for use in user initiated emergency 239 * situations, and should be used extremely cautiously. Defaults to false. 240 * 241 * <p>Permissions enforcement occurs when resulting last location request is actually used, 242 * not when this method is invoked. 243 * 244 * @hide 245 */ 246 @SystemApi 247 @RequiresPermission(LOCATION_BYPASS) setLocationSettingsIgnored(boolean locationSettingsIgnored)248 public @NonNull Builder setLocationSettingsIgnored(boolean locationSettingsIgnored) { 249 mLocationSettingsIgnored = locationSettingsIgnored; 250 return this; 251 } 252 253 /** 254 * Builds a last location request from this builder. 255 * 256 * @return a new last location request 257 */ build()258 public @NonNull LastLocationRequest build() { 259 return new LastLocationRequest( 260 mHiddenFromAppOps, 261 mAdasGnssBypass, 262 mLocationSettingsIgnored); 263 } 264 } 265 } 266