6eed56ddd3
This change adds a "BluetoothPermissionChecker" that ensures that all Bluetooth permission annotations are consistent. In addition, it verifies that all Bluetooth public APIs have been audited to be permission protected where relevant. We've currently standardized on saying that APIs that return device or Bluetooth state information (without sharing details about any particular remote Bluetooth device) do not need to be permission protected. This change is only annotations and has no behavior changes. Bug: 183626724 Test: ./build/soong/soong_ui.bash --make-mode Bluetooth RUN_ERROR_PRONE=true Change-Id: Ie80b15b058359bf1e9a6ee881b89cb3e5b584ca1
137 lines
5.5 KiB
Java
137 lines
5.5 KiB
Java
/*
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package android.annotation;
|
|
|
|
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
|
import static java.lang.annotation.ElementType.CONSTRUCTOR;
|
|
import static java.lang.annotation.ElementType.FIELD;
|
|
import static java.lang.annotation.ElementType.METHOD;
|
|
import static java.lang.annotation.ElementType.PARAMETER;
|
|
import static java.lang.annotation.RetentionPolicy.CLASS;
|
|
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.Target;
|
|
|
|
/**
|
|
* Denotes that the annotated element requires (or may require) one or more permissions.
|
|
* <p/>
|
|
* Example of requiring a single permission:
|
|
* <pre>{@code
|
|
* {@literal @}RequiresPermission(Manifest.permission.SET_WALLPAPER)
|
|
* public abstract void setWallpaper(Bitmap bitmap) throws IOException;
|
|
*
|
|
* {@literal @}RequiresPermission(ACCESS_COARSE_LOCATION)
|
|
* public abstract Location getLastKnownLocation(String provider);
|
|
* }</pre>
|
|
* Example of requiring at least one permission from a set:
|
|
* <pre>{@code
|
|
* {@literal @}RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
|
|
* public abstract Location getLastKnownLocation(String provider);
|
|
* }</pre>
|
|
* Example of requiring multiple permissions:
|
|
* <pre>{@code
|
|
* {@literal @}RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
|
|
* public abstract Location getLastKnownLocation(String provider);
|
|
* }</pre>
|
|
* Example of requiring separate read and write permissions for a content provider:
|
|
* <pre>{@code
|
|
* {@literal @}RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
|
|
* {@literal @}RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
|
|
* public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
|
|
* }</pre>
|
|
* <p>
|
|
* When specified on a parameter, the annotation indicates that the method requires
|
|
* a permission which depends on the value of the parameter. For example, consider
|
|
* {@link android.app.Activity#startActivity(android.content.Intent)
|
|
* Activity#startActivity(Intent)}:
|
|
* <pre>{@code
|
|
* public void startActivity(@RequiresPermission Intent intent) { ... }
|
|
* }</pre>
|
|
* Notice how there are no actual permission names listed in the annotation. The actual
|
|
* permissions required will depend on the particular intent passed in. For example,
|
|
* the code may look like this:
|
|
* <pre>{@code
|
|
* Intent intent = new Intent(Intent.ACTION_CALL);
|
|
* startActivity(intent);
|
|
* }</pre>
|
|
* and the actual permission requirement for this particular intent is described on
|
|
* the Intent name itself:
|
|
* <pre>{@code
|
|
* {@literal @}RequiresPermission(Manifest.permission.CALL_PHONE)
|
|
* public static final String ACTION_CALL = "android.intent.action.CALL";
|
|
* }</pre>
|
|
*
|
|
* @hide
|
|
*/
|
|
@Retention(CLASS)
|
|
@Target({ANNOTATION_TYPE,METHOD,CONSTRUCTOR,FIELD,PARAMETER})
|
|
public @interface RequiresPermission {
|
|
/**
|
|
* The name of the permission that is required, if precisely one permission
|
|
* is required. If more than one permission is required, specify either
|
|
* {@link #allOf()} or {@link #anyOf()} instead.
|
|
* <p>
|
|
* If specified, {@link #anyOf()} and {@link #allOf()} must both be null.
|
|
*/
|
|
String value() default "";
|
|
|
|
/**
|
|
* Specifies a list of permission names that are all required.
|
|
* <p>
|
|
* If specified, {@link #anyOf()} and {@link #value()} must both be null.
|
|
*/
|
|
String[] allOf() default {};
|
|
|
|
/**
|
|
* Specifies a list of permission names where at least one is required
|
|
* <p>
|
|
* If specified, {@link #allOf()} and {@link #value()} must both be null.
|
|
*/
|
|
String[] anyOf() default {};
|
|
|
|
/**
|
|
* If true, the permission may not be required in all cases (e.g. it may only be
|
|
* enforced on certain platforms, or for certain call parameters, etc.
|
|
*/
|
|
boolean conditional() default false;
|
|
|
|
/**
|
|
* Specifies that the given permission is required for read operations.
|
|
* <p>
|
|
* When specified on a parameter, the annotation indicates that the method requires
|
|
* a permission which depends on the value of the parameter (and typically
|
|
* the corresponding field passed in will be one of a set of constants which have
|
|
* been annotated with a <code>@RequiresPermission</code> annotation.)
|
|
*/
|
|
@Target({FIELD, METHOD, PARAMETER})
|
|
@interface Read {
|
|
RequiresPermission value() default @RequiresPermission;
|
|
}
|
|
|
|
/**
|
|
* Specifies that the given permission is required for write operations.
|
|
* <p>
|
|
* When specified on a parameter, the annotation indicates that the method requires
|
|
* a permission which depends on the value of the parameter (and typically
|
|
* the corresponding field passed in will be one of a set of constants which have
|
|
* been annotated with a <code>@RequiresPermission</code> annotation.)
|
|
*/
|
|
@Target({FIELD, METHOD, PARAMETER})
|
|
@interface Write {
|
|
RequiresPermission value() default @RequiresPermission;
|
|
}
|
|
}
|