diff --git a/Android.bp b/Android.bp
index 8a3f76c40e868cc3015798e0905af60ef2f42859..b9b1bd87e80d3682da061f305fe44d36e4d44451 100644
--- a/Android.bp
+++ b/Android.bp
@@ -721,6 +721,7 @@ java_defaults {
"frameworks/av/camera/aidl",
"frameworks/av/media/libaudioclient/aidl",
"frameworks/native/aidl/gui",
+ "frameworks/native/libs/incidentcompanion/binder",
"system/core/storaged/binder",
"system/vold/binder",
"system/gsid/aidl",
@@ -968,7 +969,10 @@ java_library {
output_params: ["store_unknown_fields=true"],
include_dirs: ["external/protobuf/src"],
},
-
+ exclude_srcs: [
+ "core/proto/android/privacy.proto",
+ "core/proto/android/section.proto",
+ ],
sdk_version: "current",
srcs: [
"core/proto/**/*.proto",
@@ -988,6 +992,10 @@ java_library {
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
],
+ exclude_srcs: [
+ "core/proto/android/privacy.proto",
+ "core/proto/android/section.proto",
+ ],
// Protos have lots of MissingOverride and similar.
errorprone: {
javacflags: ["-XepDisableAllChecks"],
@@ -995,9 +1003,9 @@ java_library {
}
// ==== c++ proto device library ==============================
-cc_library {
- name: "libplatformprotos",
- host_supported: true,
+cc_defaults {
+ name: "libplatformprotos-defaults",
+
proto: {
export_proto_headers: true,
include_dirs: ["external/protobuf/src"],
@@ -1011,8 +1019,13 @@ cc_library {
srcs: [
"core/proto/**/*.proto",
- "libs/incident/**/*.proto",
],
+}
+
+cc_library {
+ name: "libplatformprotos",
+ defaults: ["libplatformprotos-defaults"],
+ host_supported: true,
target: {
host: {
@@ -1024,6 +1037,9 @@ cc_library {
proto: {
type: "lite",
},
+ shared_libs: [
+ "libprotobuf-cpp-lite",
+ ],
shared: {
enabled: false,
},
@@ -1031,6 +1047,26 @@ cc_library {
},
}
+// This is the full proto version of libplatformprotos. It may only
+// be used by test code that is not shipped on the device.
+cc_library {
+ name: "libplatformprotos-test",
+ defaults: ["libplatformprotos-defaults"],
+ host_supported: false,
+
+ target: {
+ android: {
+ proto: {
+ type: "full",
+ },
+ shared: {
+ enabled: false,
+ },
+ },
+ },
+}
+
+
gensrcs {
name: "gen-platform-proto-constants",
depfile: true,
@@ -1068,6 +1104,7 @@ gensrcs {
output_extension: "proto.h",
}
+
subdirs = [
"cmds/*",
"core/*",
diff --git a/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java b/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java
index 0c30302d63a3f815c884a3dcca1845d431e529c8..1f261882b2d3a416f9918a8790219ff85f86c8bc 100644
--- a/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java
+++ b/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java
@@ -47,7 +47,7 @@ public class KernelCpuThreadReaderPerfTest {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
assertNotNull(mKernelCpuThreadReader);
while (state.keepRunning()) {
- this.mKernelCpuThreadReader.getCurrentProcessCpuUsage();
+ this.mKernelCpuThreadReader.getProcessCpuUsage();
}
}
}
diff --git a/apct-tests/perftests/textclassifier/Android.bp b/apct-tests/perftests/textclassifier/Android.bp
new file mode 100644
index 0000000000000000000000000000000000000000..49952dc1d009d20cf137f0a173cbab699a8d7a60
--- /dev/null
+++ b/apct-tests/perftests/textclassifier/Android.bp
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 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.
+
+android_test {
+ name: "TextClassifierPerfTests",
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "androidx.test.rules",
+ "androidx.annotation_annotation",
+ "apct-perftests-utils",
+ ],
+ platform_apis: true,
+ test_suites: ["device-tests"],
+}
diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml b/apct-tests/perftests/textclassifier/AndroidManifest.xml
similarity index 58%
rename from packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml
rename to apct-tests/perftests/textclassifier/AndroidManifest.xml
index e17b5335c55d62072b57c12e9c089ae708026a71..7cf487f2eb7efb93049d60e5c5c6691891b12d70 100644
--- a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml
+++ b/apct-tests/perftests/textclassifier/AndroidManifest.xml
@@ -1,6 +1,5 @@
-
+
-
+
+
+
+
+
+
diff --git a/apct-tests/perftests/textclassifier/AndroidTest.xml b/apct-tests/perftests/textclassifier/AndroidTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3df51b8ae67af8e018d5441cbf6fdefddafb477b
--- /dev/null
+++ b/apct-tests/perftests/textclassifier/AndroidTest.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apct-tests/perftests/textclassifier/run.sh b/apct-tests/perftests/textclassifier/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c6782d1a72f26122527925b22f4b775dabc807c1
--- /dev/null
+++ b/apct-tests/perftests/textclassifier/run.sh
@@ -0,0 +1,4 @@
+set -e
+make TextClassifierPerfTests
+adb shell cmd package compile -m speed -f com.android.perftests.textclassifier
+adb shell am instrument -w -e class android.view.textclassifier.TextClassifierPerfTest com.android.perftests.textclassifier/androidx.test.runner.AndroidJUnitRunner
diff --git a/apct-tests/perftests/core/src/android/textclassifier/TextClassifierPerfTest.java b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassifierPerfTest.java
similarity index 94%
rename from apct-tests/perftests/core/src/android/textclassifier/TextClassifierPerfTest.java
rename to apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassifierPerfTest.java
index c5d89b234209d282b67e8b181c53cd9ba98e57d7..14a121d60c2e585ef6f4c39796e5e0d283e25a9d 100644
--- a/apct-tests/perftests/core/src/android/textclassifier/TextClassifierPerfTest.java
+++ b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassifierPerfTest.java
@@ -13,15 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.textclassifier;
+package android.view.textclassifier;
import android.content.Context;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
-import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.TextClassificationManager;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextLanguage;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
diff --git a/api/current.txt b/api/current.txt
index 5664d4f65cc4ff50d45889ae6a11c8178b0d67f8..1394ba33dddd9a13da8f7e4e0b9c95be84b04e73 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -102,16 +102,13 @@ package android {
field public static final String NFC_TRANSACTION_EVENT = "android.permission.NFC_TRANSACTION_EVENT";
field public static final String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
field @Deprecated public static final String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
- field public static final String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
+ field @Deprecated public static final String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
field public static final String READ_CALENDAR = "android.permission.READ_CALENDAR";
field public static final String READ_CALL_LOG = "android.permission.READ_CALL_LOG";
field public static final String READ_CONTACTS = "android.permission.READ_CONTACTS";
- field @Deprecated public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
+ field public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
field @Deprecated public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final String READ_LOGS = "android.permission.READ_LOGS";
- field public static final String READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO";
- field public static final String READ_MEDIA_IMAGES = "android.permission.READ_MEDIA_IMAGES";
- field public static final String READ_MEDIA_VIDEO = "android.permission.READ_MEDIA_VIDEO";
field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
field public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final String READ_SMS = "android.permission.READ_SMS";
@@ -161,7 +158,7 @@ package android {
field public static final String WRITE_CALENDAR = "android.permission.WRITE_CALENDAR";
field public static final String WRITE_CALL_LOG = "android.permission.WRITE_CALL_LOG";
field public static final String WRITE_CONTACTS = "android.permission.WRITE_CONTACTS";
- field @Deprecated public static final String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
+ field public static final String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
field public static final String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";
field public static final String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
field public static final String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";
@@ -177,13 +174,11 @@ package android {
field public static final String CAMERA = "android.permission-group.CAMERA";
field public static final String CONTACTS = "android.permission-group.CONTACTS";
field public static final String LOCATION = "android.permission-group.LOCATION";
- field public static final String MEDIA_AURAL = "android.permission-group.MEDIA_AURAL";
- field public static final String MEDIA_VISUAL = "android.permission-group.MEDIA_VISUAL";
field public static final String MICROPHONE = "android.permission-group.MICROPHONE";
field public static final String PHONE = "android.permission-group.PHONE";
field public static final String SENSORS = "android.permission-group.SENSORS";
field public static final String SMS = "android.permission-group.SMS";
- field @Deprecated public static final String STORAGE = "android.permission-group.STORAGE";
+ field public static final String STORAGE = "android.permission-group.STORAGE";
}
public final class R {
@@ -291,6 +286,7 @@ package android {
field public static final int allowBackup = 16843392; // 0x1010280
field public static final int allowClearUserData = 16842757; // 0x1010005
field public static final int allowEmbedded = 16843765; // 0x10103f5
+ field public static final int allowExternalStorageSandbox = 16844201; // 0x10105a9
field public static final int allowParallelSyncs = 16843570; // 0x1010332
field public static final int allowSingleTap = 16843353; // 0x1010259
field public static final int allowTaskReparenting = 16843268; // 0x1010204
@@ -5480,7 +5476,7 @@ package android.app {
method public int describeContents();
method public boolean getAutoExpandBubble();
method @Nullable public android.app.PendingIntent getDeleteIntent();
- method public int getDesiredHeight();
+ method @Dimension(unit=android.annotation.Dimension.DP) public int getDesiredHeight();
method @DimenRes public int getDesiredHeightResId();
method @NonNull public android.graphics.drawable.Icon getIcon();
method @NonNull public android.app.PendingIntent getIntent();
@@ -5494,7 +5490,7 @@ package android.app {
method @NonNull public android.app.Notification.BubbleMetadata build();
method @NonNull public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean);
method @NonNull public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(@Nullable android.app.PendingIntent);
- method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int);
+ method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(@Dimension(unit=android.annotation.Dimension.DP) int);
method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
method @NonNull public android.app.Notification.BubbleMetadata.Builder setIcon(@NonNull android.graphics.drawable.Icon);
method @NonNull public android.app.Notification.BubbleMetadata.Builder setIntent(@NonNull android.app.PendingIntent);
@@ -6273,7 +6269,7 @@ package android.app {
public final class UiAutomation {
method public void adoptShellPermissionIdentity();
- method public void adoptShellPermissionIdentity(java.lang.String...);
+ method public void adoptShellPermissionIdentity(@Nullable java.lang.String...);
method public void clearWindowAnimationFrameStats();
method public boolean clearWindowContentFrameStats(int);
method public void dropShellPermissionIdentity();
@@ -6963,7 +6959,7 @@ package android.app.admin {
public abstract static class DevicePolicyManager.InstallSystemUpdateCallback {
ctor public DevicePolicyManager.InstallSystemUpdateCallback();
- method public void onInstallUpdateError(int, String);
+ method public void onInstallUpdateError(int, @NonNull String);
field public static final int UPDATE_ERROR_BATTERY_LOW = 5; // 0x5
field public static final int UPDATE_ERROR_FILE_NOT_FOUND = 4; // 0x4
field public static final int UPDATE_ERROR_INCORRECT_OS_VERSION = 2; // 0x2
@@ -8604,7 +8600,6 @@ package android.bluetooth {
}
@Deprecated public final class BluetoothHealth implements android.bluetooth.BluetoothProfile {
- ctor @Deprecated public BluetoothHealth();
method @Deprecated public boolean connectChannelToSource(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration);
method @Deprecated public boolean disconnectChannel(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration, int);
method @Deprecated public java.util.List getConnectedDevices();
@@ -8628,7 +8623,6 @@ package android.bluetooth {
}
@Deprecated public final class BluetoothHealthAppConfiguration implements android.os.Parcelable {
- ctor @Deprecated public BluetoothHealthAppConfiguration();
method @Deprecated public int describeContents();
method @Deprecated public int getDataType();
method @Deprecated public String getName();
@@ -11251,7 +11245,6 @@ package android.content.pm {
public class LauncherApps {
method public java.util.List getActivityList(String, android.os.UserHandle);
method @NonNull public java.util.List getAllPackageInstallerSessions();
- method @Nullable public android.content.pm.LauncherApps.AppUsageLimit getAppUsageLimit(@NonNull String, @NonNull android.os.UserHandle);
method public android.content.pm.ApplicationInfo getApplicationInfo(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
method public java.util.List getProfiles();
@@ -11282,14 +11275,6 @@ package android.content.pm {
field public static final String EXTRA_PIN_ITEM_REQUEST = "android.content.pm.extra.PIN_ITEM_REQUEST";
}
- public static final class LauncherApps.AppUsageLimit implements android.os.Parcelable {
- method public int describeContents();
- method public long getTotalUsageLimit();
- method public long getUsageRemaining();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- }
-
public abstract static class LauncherApps.Callback {
ctor public LauncherApps.Callback();
method public abstract void onPackageAdded(String, android.os.UserHandle);
@@ -11453,7 +11438,7 @@ package android.content.pm {
method @Nullable public android.graphics.Bitmap getAppIcon();
method @Nullable public CharSequence getAppLabel();
method @Nullable public String getAppPackageName();
- method public int[] getChildSessionIds();
+ method @NonNull public int[] getChildSessionIds();
method public int getInstallLocation();
method public int getInstallReason();
method @Nullable public String getInstallerPackageName();
@@ -11534,107 +11519,107 @@ package android.content.pm {
public abstract class PackageManager {
ctor public PackageManager();
- method @Deprecated public abstract void addPackageToPreferred(String);
- method public abstract boolean addPermission(android.content.pm.PermissionInfo);
- method public abstract boolean addPermissionAsync(android.content.pm.PermissionInfo);
- method @Deprecated public abstract void addPreferredActivity(android.content.IntentFilter, int, android.content.ComponentName[], android.content.ComponentName);
+ method @Deprecated public abstract void addPackageToPreferred(@NonNull String);
+ method public abstract boolean addPermission(@NonNull android.content.pm.PermissionInfo);
+ method public abstract boolean addPermissionAsync(@NonNull android.content.pm.PermissionInfo);
+ method @Deprecated public abstract void addPreferredActivity(@NonNull android.content.IntentFilter, int, @Nullable android.content.ComponentName[], @NonNull android.content.ComponentName);
method public abstract boolean canRequestPackageInstalls();
- method public abstract String[] canonicalToCurrentPackageNames(String[]);
- method @CheckResult public abstract int checkPermission(String, String);
- method @CheckResult public abstract int checkSignatures(String, String);
+ method public abstract String[] canonicalToCurrentPackageNames(@NonNull String[]);
+ method @CheckResult public abstract int checkPermission(@NonNull String, @NonNull String);
+ method @CheckResult public abstract int checkSignatures(@NonNull String, @NonNull String);
method @CheckResult public abstract int checkSignatures(int, int);
method public abstract void clearInstantAppCookie();
- method @Deprecated public abstract void clearPackagePreferredActivities(String);
- method public abstract String[] currentToCanonicalPackageNames(String[]);
+ method @Deprecated public abstract void clearPackagePreferredActivities(@NonNull String);
+ method public abstract String[] currentToCanonicalPackageNames(@NonNull String[]);
method public abstract void extendVerificationTimeout(int, int, long);
- method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract java.util.List getAllPermissionGroups(int);
- method public abstract android.graphics.drawable.Drawable getApplicationBanner(android.content.pm.ApplicationInfo);
- method public abstract android.graphics.drawable.Drawable getApplicationBanner(String) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @Nullable public abstract android.graphics.drawable.Drawable getActivityBanner(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @Nullable public abstract android.graphics.drawable.Drawable getActivityBanner(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.graphics.drawable.Drawable getActivityIcon(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.graphics.drawable.Drawable getActivityIcon(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.content.pm.ActivityInfo getActivityInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @Nullable public abstract android.graphics.drawable.Drawable getActivityLogo(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @Nullable public abstract android.graphics.drawable.Drawable getActivityLogo(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract java.util.List getAllPermissionGroups(int);
+ method @Nullable public abstract android.graphics.drawable.Drawable getApplicationBanner(@NonNull android.content.pm.ApplicationInfo);
+ method @Nullable public abstract android.graphics.drawable.Drawable getApplicationBanner(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract int getApplicationEnabledSetting(@NonNull String);
- method public abstract android.graphics.drawable.Drawable getApplicationIcon(android.content.pm.ApplicationInfo);
- method public abstract android.graphics.drawable.Drawable getApplicationIcon(String) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.pm.ApplicationInfo getApplicationInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract CharSequence getApplicationLabel(android.content.pm.ApplicationInfo);
- method public abstract android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo);
- method public abstract android.graphics.drawable.Drawable getApplicationLogo(String) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.graphics.drawable.Drawable getApplicationIcon(@NonNull android.content.pm.ApplicationInfo);
+ method @NonNull public abstract android.graphics.drawable.Drawable getApplicationIcon(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.content.pm.ApplicationInfo getApplicationInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract CharSequence getApplicationLabel(@NonNull android.content.pm.ApplicationInfo);
+ method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull android.content.pm.ApplicationInfo);
+ method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method @Nullable public abstract android.content.pm.ChangedPackages getChangedPackages(@IntRange(from=0) int);
method public abstract int getComponentEnabledSetting(@NonNull android.content.ComponentName);
- method public abstract android.graphics.drawable.Drawable getDefaultActivityIcon();
- method public abstract android.graphics.drawable.Drawable getDrawable(String, @DrawableRes int, android.content.pm.ApplicationInfo);
- method public abstract java.util.List getInstalledApplications(int);
+ method @NonNull public abstract android.graphics.drawable.Drawable getDefaultActivityIcon();
+ method @Nullable public abstract android.graphics.drawable.Drawable getDrawable(@NonNull String, @DrawableRes int, @Nullable android.content.pm.ApplicationInfo);
+ method @NonNull public abstract java.util.List getInstalledApplications(int);
method @NonNull public java.util.List getInstalledModules(int);
- method public abstract java.util.List getInstalledPackages(int);
- method @Nullable public abstract String getInstallerPackageName(String);
+ method @NonNull public abstract java.util.List getInstalledPackages(int);
+ method @Nullable public abstract String getInstallerPackageName(@NonNull String);
method @NonNull public abstract byte[] getInstantAppCookie();
method public abstract int getInstantAppCookieMaxBytes();
- method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method @Nullable public abstract android.content.Intent getLaunchIntentForPackage(@NonNull String);
method @Nullable public abstract android.content.Intent getLeanbackLaunchIntentForPackage(@NonNull String);
- method public android.content.pm.ModuleInfo getModuleInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public android.content.pm.ModuleInfo getModuleInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method @Nullable public abstract String getNameForUid(int);
- method public android.content.pm.PackageInfo getPackageArchiveInfo(String, int);
+ method @Nullable public android.content.pm.PackageInfo getPackageArchiveInfo(@NonNull String, int);
method public abstract int[] getPackageGids(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract int[] getPackageGids(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.pm.PackageInfo getPackageInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public abstract int[] getPackageGids(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public abstract android.content.pm.PackageInfo getPackageInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public abstract android.content.pm.PackageInfo getPackageInfo(@NonNull android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public abstract android.content.pm.PackageInstaller getPackageInstaller();
- method public abstract int getPackageUid(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public abstract int getPackageUid(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method @Nullable public abstract String[] getPackagesForUid(int);
- method public abstract java.util.List getPackagesHoldingPermissions(String[], int);
- method public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.pm.PermissionInfo getPermissionInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method @Deprecated public abstract int getPreferredActivities(@NonNull java.util.List, @NonNull java.util.List, String);
- method @Deprecated public abstract java.util.List getPreferredPackages(int);
- method public abstract android.content.pm.ProviderInfo getProviderInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.pm.ActivityInfo getReceiverInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.res.Resources getResourcesForActivity(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.res.Resources getResourcesForApplication(String) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract java.util.List getPackagesHoldingPermissions(@NonNull String[], int);
+ method @NonNull public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public abstract android.content.pm.PermissionInfo getPermissionInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @Deprecated public abstract int getPreferredActivities(@NonNull java.util.List, @NonNull java.util.List, @Nullable String);
+ method @Deprecated @NonNull public abstract java.util.List getPreferredPackages(int);
+ method @NonNull public abstract android.content.pm.ProviderInfo getProviderInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.content.pm.ActivityInfo getReceiverInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.content.res.Resources getResourcesForActivity(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.content.res.Resources getResourcesForApplication(@NonNull android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.content.res.Resources getResourcesForApplication(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public abstract android.content.pm.ServiceInfo getServiceInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public abstract java.util.List getSharedLibraries(int);
method @Nullable public android.os.Bundle getSuspendedPackageAppExtras();
method public boolean getSyntheticAppDetailsActivityEnabled(@NonNull String);
- method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
- method public abstract String[] getSystemSharedLibraryNames();
- method public abstract CharSequence getText(String, @StringRes int, android.content.pm.ApplicationInfo);
- method public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(android.graphics.drawable.Drawable, android.os.UserHandle, android.graphics.Rect, int);
- method public abstract android.graphics.drawable.Drawable getUserBadgedIcon(android.graphics.drawable.Drawable, android.os.UserHandle);
- method public abstract CharSequence getUserBadgedLabel(CharSequence, android.os.UserHandle);
- method public abstract android.content.res.XmlResourceParser getXml(String, @XmlRes int, android.content.pm.ApplicationInfo);
- method public boolean hasSigningCertificate(String, byte[], int);
- method public boolean hasSigningCertificate(int, byte[], int);
- method public abstract boolean hasSystemFeature(String);
- method public abstract boolean hasSystemFeature(String, int);
+ method @NonNull public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
+ method @Nullable public abstract String[] getSystemSharedLibraryNames();
+ method @Nullable public abstract CharSequence getText(@NonNull String, @StringRes int, @Nullable android.content.pm.ApplicationInfo);
+ method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int);
+ method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle);
+ method @NonNull public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence, @NonNull android.os.UserHandle);
+ method @Nullable public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo);
+ method public boolean hasSigningCertificate(@NonNull String, @NonNull byte[], int);
+ method public boolean hasSigningCertificate(int, @NonNull byte[], int);
+ method public abstract boolean hasSystemFeature(@NonNull String);
+ method public abstract boolean hasSystemFeature(@NonNull String, int);
method public abstract boolean isInstantApp();
- method public abstract boolean isInstantApp(String);
- method public boolean isPackageSuspended(String) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public abstract boolean isInstantApp(@NonNull String);
+ method public boolean isPackageSuspended(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method public boolean isPackageSuspended();
method @CheckResult public abstract boolean isPermissionRevokedByPolicy(@NonNull String, @NonNull String);
method public abstract boolean isSafeMode();
- method public abstract java.util.List queryBroadcastReceivers(android.content.Intent, int);
- method public abstract java.util.List queryContentProviders(String, int, int);
- method public abstract java.util.List queryInstrumentation(String, int);
- method public abstract java.util.List queryIntentActivities(android.content.Intent, int);
- method public abstract java.util.List queryIntentActivityOptions(@Nullable android.content.ComponentName, @Nullable android.content.Intent[], android.content.Intent, int);
- method public abstract java.util.List queryIntentContentProviders(android.content.Intent, int);
- method public abstract java.util.List queryIntentServices(android.content.Intent, int);
- method public abstract java.util.List queryPermissionsByGroup(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method @Deprecated public abstract void removePackageFromPreferred(String);
- method public abstract void removePermission(String);
- method public abstract android.content.pm.ResolveInfo resolveActivity(android.content.Intent, int);
- method public abstract android.content.pm.ProviderInfo resolveContentProvider(String, int);
- method public abstract android.content.pm.ResolveInfo resolveService(android.content.Intent, int);
+ method @NonNull public abstract java.util.List queryBroadcastReceivers(@NonNull android.content.Intent, int);
+ method @NonNull public abstract java.util.List queryContentProviders(@Nullable String, int, int);
+ method @NonNull public abstract java.util.List queryInstrumentation(@NonNull String, int);
+ method @Nullable public abstract java.util.List queryIntentActivities(@NonNull android.content.Intent, int);
+ method @NonNull public abstract java.util.List queryIntentActivityOptions(@Nullable android.content.ComponentName, @Nullable android.content.Intent[], @NonNull android.content.Intent, int);
+ method @NonNull public abstract java.util.List queryIntentContentProviders(@NonNull android.content.Intent, int);
+ method @NonNull public abstract java.util.List queryIntentServices(@NonNull android.content.Intent, int);
+ method @NonNull public abstract java.util.List queryPermissionsByGroup(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @Deprecated public abstract void removePackageFromPreferred(@NonNull String);
+ method public abstract void removePermission(@NonNull String);
+ method @Nullable public abstract android.content.pm.ResolveInfo resolveActivity(@NonNull android.content.Intent, int);
+ method @Nullable public abstract android.content.pm.ProviderInfo resolveContentProvider(@NonNull String, int);
+ method @Nullable public abstract android.content.pm.ResolveInfo resolveService(@NonNull android.content.Intent, int);
method public abstract void setApplicationCategoryHint(@NonNull String, int);
method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public abstract void setApplicationEnabledSetting(@NonNull String, int, int);
method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public abstract void setComponentEnabledSetting(@NonNull android.content.ComponentName, int, int);
- method public abstract void setInstallerPackageName(String, String);
+ method public abstract void setInstallerPackageName(@NonNull String, @Nullable String);
method public abstract void updateInstantAppCookie(@Nullable byte[]);
method public abstract void verifyPendingInstall(int, int);
field public static final int CERT_INPUT_RAW_X509 = 0; // 0x0
@@ -13089,10 +13074,10 @@ package android.database.sqlite {
method @Deprecated public String buildUnionSubQuery(String, String[], java.util.Set, int, String, String, String[], String, String);
method public int delete(@NonNull android.database.sqlite.SQLiteDatabase, @Nullable String, @Nullable String[]);
method @Nullable public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
- method public boolean getDistinct();
method @Nullable public java.util.Map getProjectionMap();
- method public boolean getStrict();
method @Nullable public String getTables();
+ method public boolean isDistinct();
+ method public boolean isStrict();
method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String);
method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String, String);
method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String, String, android.os.CancellationSignal);
@@ -14100,8 +14085,9 @@ package android.graphics {
}
public class ComposeShader extends android.graphics.Shader {
- ctor public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.Xfermode);
- ctor public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.PorterDuff.Mode);
+ ctor @Deprecated public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.Xfermode);
+ ctor @Deprecated public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.PorterDuff.Mode);
+ ctor public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.BlendMode);
}
public class CornerPathEffect extends android.graphics.PathEffect {
@@ -14795,37 +14781,37 @@ package android.graphics {
field public float y;
}
- public class PorterDuff {
- ctor public PorterDuff();
+ @Deprecated public class PorterDuff {
+ ctor @Deprecated public PorterDuff();
}
- public enum PorterDuff.Mode {
- enum_constant public static final android.graphics.PorterDuff.Mode ADD;
- enum_constant public static final android.graphics.PorterDuff.Mode CLEAR;
- enum_constant public static final android.graphics.PorterDuff.Mode DARKEN;
- enum_constant public static final android.graphics.PorterDuff.Mode DST;
- enum_constant public static final android.graphics.PorterDuff.Mode DST_ATOP;
- enum_constant public static final android.graphics.PorterDuff.Mode DST_IN;
- enum_constant public static final android.graphics.PorterDuff.Mode DST_OUT;
- enum_constant public static final android.graphics.PorterDuff.Mode DST_OVER;
- enum_constant public static final android.graphics.PorterDuff.Mode LIGHTEN;
- enum_constant public static final android.graphics.PorterDuff.Mode MULTIPLY;
- enum_constant public static final android.graphics.PorterDuff.Mode OVERLAY;
- enum_constant public static final android.graphics.PorterDuff.Mode SCREEN;
- enum_constant public static final android.graphics.PorterDuff.Mode SRC;
- enum_constant public static final android.graphics.PorterDuff.Mode SRC_ATOP;
- enum_constant public static final android.graphics.PorterDuff.Mode SRC_IN;
- enum_constant public static final android.graphics.PorterDuff.Mode SRC_OUT;
- enum_constant public static final android.graphics.PorterDuff.Mode SRC_OVER;
- enum_constant public static final android.graphics.PorterDuff.Mode XOR;
+ @Deprecated public enum PorterDuff.Mode {
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode ADD;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode CLEAR;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DARKEN;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST_ATOP;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST_IN;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST_OUT;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST_OVER;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode LIGHTEN;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode MULTIPLY;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode OVERLAY;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SCREEN;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC_ATOP;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC_IN;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC_OUT;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC_OVER;
+ enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode XOR;
}
@Deprecated public class PorterDuffColorFilter extends android.graphics.ColorFilter {
ctor @Deprecated public PorterDuffColorFilter(@ColorInt int, @NonNull android.graphics.PorterDuff.Mode);
}
- public class PorterDuffXfermode extends android.graphics.Xfermode {
- ctor public PorterDuffXfermode(android.graphics.PorterDuff.Mode);
+ @Deprecated public class PorterDuffXfermode extends android.graphics.Xfermode {
+ ctor @Deprecated public PorterDuffXfermode(android.graphics.PorterDuff.Mode);
}
public interface PostProcessor {
@@ -15387,7 +15373,8 @@ package android.graphics.drawable {
method public boolean setState(@NonNull int[]);
method public void setTint(@ColorInt int);
method public void setTintList(@Nullable android.content.res.ColorStateList);
- method public void setTintMode(@NonNull android.graphics.PorterDuff.Mode);
+ method @Deprecated public void setTintMode(@Nullable android.graphics.PorterDuff.Mode);
+ method public void setTintMode(@Nullable android.graphics.BlendMode);
method public boolean setVisible(boolean, boolean);
method public void unscheduleSelf(@NonNull Runnable);
}
@@ -15545,7 +15532,8 @@ package android.graphics.drawable {
method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler);
method public android.graphics.drawable.Icon setTint(@ColorInt int);
method public android.graphics.drawable.Icon setTintList(android.content.res.ColorStateList);
- method public android.graphics.drawable.Icon setTintMode(android.graphics.PorterDuff.Mode);
+ method @Deprecated @NonNull public android.graphics.drawable.Icon setTintMode(@NonNull android.graphics.PorterDuff.Mode);
+ method @NonNull public android.graphics.drawable.Icon setTintMode(@NonNull android.graphics.BlendMode);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
field public static final int TYPE_ADAPTIVE_BITMAP = 5; // 0x5
@@ -17054,6 +17042,7 @@ package android.hardware.camera2 {
public class CaptureFailure {
method public long getFrameNumber();
+ method @Nullable public String getPhysicalCameraId();
method public int getReason();
method @NonNull public android.hardware.camera2.CaptureRequest getRequest();
method public int getSequenceId();
@@ -23041,6 +23030,9 @@ package android.media {
method public int getUsage();
method public int getVolumeControlStream();
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int ALLOW_CAPTURE_BY_ALL = 1; // 0x1
+ field public static final int ALLOW_CAPTURE_BY_NONE = 3; // 0x3
+ field public static final int ALLOW_CAPTURE_BY_SYSTEM = 2; // 0x2
field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
field public static final int CONTENT_TYPE_SONIFICATION = 4; // 0x4
@@ -23072,7 +23064,7 @@ package android.media {
ctor public AudioAttributes.Builder();
ctor public AudioAttributes.Builder(android.media.AudioAttributes);
method public android.media.AudioAttributes build();
- method @NonNull public android.media.AudioAttributes.Builder setAllowCapture(boolean);
+ method @NonNull public android.media.AudioAttributes.Builder setAllowedCapturePolicy(int);
method public android.media.AudioAttributes.Builder setContentType(int);
method public android.media.AudioAttributes.Builder setFlags(int);
method public android.media.AudioAttributes.Builder setLegacyStreamType(int);
@@ -23273,6 +23265,7 @@ package android.media {
method @Deprecated public boolean registerRemoteController(android.media.RemoteController);
method @Deprecated public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
method public int requestAudioFocus(@NonNull android.media.AudioFocusRequest);
+ method public void setAllowedCapturePolicy(int);
method @Deprecated public void setBluetoothA2dpOn(boolean);
method public void setBluetoothScoOn(boolean);
method public void setMicrophoneMute(boolean);
@@ -25069,7 +25062,7 @@ package android.media {
field public static final String KEY_LANGUAGE = "language";
field public static final String KEY_LATENCY = "latency";
field public static final String KEY_LEVEL = "level";
- field public static final String KEY_MAX_BFRAMES = "max-bframes";
+ field public static final String KEY_MAX_B_FRAMES = "max-bframes";
field public static final String KEY_MAX_FPS_TO_ENCODER = "max-fps-to-encoder";
field public static final String KEY_MAX_HEIGHT = "max-height";
field public static final String KEY_MAX_INPUT_SIZE = "max-input-size";
@@ -28712,12 +28705,12 @@ package android.net {
public static class ConnectivityManager.NetworkCallback {
ctor public ConnectivityManager.NetworkCallback();
- method public void onAvailable(android.net.Network);
+ method public void onAvailable(@NonNull android.net.Network);
method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
- method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities);
- method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
- method public void onLosing(android.net.Network, int);
- method public void onLost(android.net.Network);
+ method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities);
+ method public void onLinkPropertiesChanged(@NonNull android.net.Network, @NonNull android.net.LinkProperties);
+ method public void onLosing(@NonNull android.net.Network, int);
+ method public void onLost(@NonNull android.net.Network);
method public void onUnavailable();
}
@@ -28749,6 +28742,7 @@ package android.net {
method @NonNull public static android.net.DnsResolver getInstance();
method public void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback);
method public void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback);
+ method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.InetAddressAnswerCallback);
field public static final int CLASS_IN = 1; // 0x1
field public static final int FLAG_EMPTY = 0; // 0x0
field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4
@@ -28783,11 +28777,11 @@ package android.net {
}
public final class IpPrefix implements android.os.Parcelable {
- method public boolean contains(java.net.InetAddress);
+ method public boolean contains(@NonNull java.net.InetAddress);
method public int describeContents();
- method public java.net.InetAddress getAddress();
- method public int getPrefixLength();
- method public byte[] getRawAddress();
+ method @NonNull public java.net.InetAddress getAddress();
+ method @IntRange(from=0, to=128) public int getPrefixLength();
+ method @NonNull public byte[] getRawAddress();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
}
@@ -28860,7 +28854,7 @@ package android.net {
method public int describeContents();
method public java.net.InetAddress getAddress();
method public int getFlags();
- method public int getPrefixLength();
+ method @IntRange(from=0, to=128) public int getPrefixLength();
method public int getScope();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
@@ -29130,9 +29124,9 @@ package android.net {
public final class RouteInfo implements android.os.Parcelable {
method public int describeContents();
- method public android.net.IpPrefix getDestination();
- method public java.net.InetAddress getGateway();
- method public String getInterface();
+ method @NonNull public android.net.IpPrefix getDestination();
+ method @Nullable public java.net.InetAddress getGateway();
+ method @Nullable public String getInterface();
method public boolean hasGateway();
method public boolean isDefaultRoute();
method public boolean matches(java.net.InetAddress);
@@ -29267,7 +29261,6 @@ package android.net {
method public abstract boolean isRelative();
method public android.net.Uri normalizeScheme();
method public static android.net.Uri parse(String);
- method @NonNull public String toSafeString();
method public abstract String toString();
method public static android.net.Uri withAppendedPath(android.net.Uri, String);
method public static void writeToParcel(android.os.Parcel, android.net.Uri);
@@ -34652,9 +34645,11 @@ package android.os {
method @NonNull public static java.io.File getRootDirectory();
method @Deprecated public static String getStorageState(java.io.File);
method public static boolean isExternalStorageEmulated();
- method public static boolean isExternalStorageEmulated(java.io.File);
+ method public static boolean isExternalStorageEmulated(@NonNull java.io.File);
method public static boolean isExternalStorageRemovable();
- method public static boolean isExternalStorageRemovable(java.io.File);
+ method public static boolean isExternalStorageRemovable(@NonNull java.io.File);
+ method public static boolean isExternalStorageSandboxed();
+ method public static boolean isExternalStorageSandboxed(@NonNull java.io.File);
field public static String DIRECTORY_ALARMS;
field public static String DIRECTORY_AUDIOBOOKS;
field public static String DIRECTORY_DCIM;
@@ -38852,6 +38847,7 @@ package android.provider {
field public static final String ACTION_APPLICATION_DETAILS_SETTINGS = "android.settings.APPLICATION_DETAILS_SETTINGS";
field public static final String ACTION_APPLICATION_DEVELOPMENT_SETTINGS = "android.settings.APPLICATION_DEVELOPMENT_SETTINGS";
field public static final String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
+ field public static final String ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS = "android.settings.APP_NOTIFICATION_BUBBLE_SETTINGS";
field public static final String ACTION_APP_NOTIFICATION_SETTINGS = "android.settings.APP_NOTIFICATION_SETTINGS";
field public static final String ACTION_APP_SEARCH_SETTINGS = "android.settings.APP_SEARCH_SETTINGS";
field public static final String ACTION_APP_USAGE_SETTINGS = "android.settings.action.APP_USAGE_SETTINGS";
@@ -42523,6 +42519,7 @@ package android.system {
method public static int getpid();
method public static int getppid();
method public static java.net.SocketAddress getsockname(java.io.FileDescriptor) throws android.system.ErrnoException;
+ method @NonNull public static android.system.StructTimeval getsockoptTimeval(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
method public static int gettid();
method public static int getuid();
method public static byte[] getxattr(String, String) throws android.system.ErrnoException;
@@ -42573,6 +42570,7 @@ package android.system {
method @Deprecated public static void setgid(int) throws android.system.ErrnoException;
method public static int setsid() throws android.system.ErrnoException;
method public static void setsockoptInt(java.io.FileDescriptor, int, int, int) throws android.system.ErrnoException;
+ method public static void setsockoptTimeval(@NonNull java.io.FileDescriptor, int, int, @NonNull android.system.StructTimeval) throws android.system.ErrnoException;
method @Deprecated public static void setuid(int) throws android.system.ErrnoException;
method public static void setxattr(String, String, byte[], int) throws android.system.ErrnoException;
method public static void shutdown(java.io.FileDescriptor, int) throws android.system.ErrnoException;
@@ -42778,6 +42776,10 @@ package android.system {
field public static final int F_SETOWN;
field public static final int F_UNLCK;
field public static final int F_WRLCK;
+ field public static final int ICMP6_ECHO_REPLY;
+ field public static final int ICMP6_ECHO_REQUEST;
+ field public static final int ICMP_ECHO;
+ field public static final int ICMP_ECHOREPLY;
field public static final int IFA_F_DADFAILED;
field public static final int IFA_F_DEPRECATED;
field public static final int IFA_F_HOMEADDRESS;
@@ -43150,6 +43152,13 @@ package android.system {
field public final long tv_sec;
}
+ public final class StructTimeval {
+ method @NonNull public static android.system.StructTimeval fromMillis(long);
+ method public long toMillis();
+ field public final long tv_sec;
+ field public final long tv_usec;
+ }
+
public final class StructUtsname {
ctor public StructUtsname(String, String, String, String, String);
field public final String machine;
@@ -49719,8 +49728,9 @@ package android.view {
method public default CharSequence getContentDescription();
method public int getGroupId();
method public android.graphics.drawable.Drawable getIcon();
+ method @Nullable public default android.graphics.BlendMode getIconTintBlendMode();
method @Nullable public default android.content.res.ColorStateList getIconTintList();
- method @Nullable public default android.graphics.PorterDuff.Mode getIconTintMode();
+ method @Deprecated @Nullable public default android.graphics.PorterDuff.Mode getIconTintMode();
method public android.content.Intent getIntent();
method public int getItemId();
method public android.view.ContextMenu.ContextMenuInfo getMenuInfo();
@@ -49749,7 +49759,8 @@ package android.view {
method public android.view.MenuItem setIcon(android.graphics.drawable.Drawable);
method public android.view.MenuItem setIcon(@DrawableRes int);
method public default android.view.MenuItem setIconTintList(@Nullable android.content.res.ColorStateList);
- method public default android.view.MenuItem setIconTintMode(@Nullable android.graphics.PorterDuff.Mode);
+ method @Deprecated @NonNull public default android.view.MenuItem setIconTintMode(@Nullable android.graphics.PorterDuff.Mode);
+ method @NonNull public default android.view.MenuItem setIconTintMode(@Nullable android.graphics.BlendMode);
method public android.view.MenuItem setIntent(android.content.Intent);
method public android.view.MenuItem setNumericShortcut(char);
method public default android.view.MenuItem setNumericShortcut(char, int);
@@ -50402,8 +50413,9 @@ package android.view {
method public int getAutofillType();
method @Nullable public android.view.autofill.AutofillValue getAutofillValue();
method public android.graphics.drawable.Drawable getBackground();
+ method @Nullable public android.graphics.BlendMode getBackgroundBlendMode();
method @Nullable public android.content.res.ColorStateList getBackgroundTintList();
- method @Nullable public android.graphics.PorterDuff.Mode getBackgroundTintMode();
+ method @Deprecated @Nullable public android.graphics.PorterDuff.Mode getBackgroundTintMode();
method @android.view.ViewDebug.ExportedProperty(category="layout") public int getBaseline();
method @android.view.ViewDebug.CapturedViewProperty public final int getBottom();
method protected float getBottomFadingEdgeStrength();
@@ -50434,9 +50446,10 @@ package android.view {
method public java.util.ArrayList getFocusables(int);
method public void getFocusedRect(android.graphics.Rect);
method public android.graphics.drawable.Drawable getForeground();
+ method @Nullable public android.graphics.BlendMode getForegroundBlendMode();
method public int getForegroundGravity();
method @Nullable public android.content.res.ColorStateList getForegroundTintList();
- method @Nullable public android.graphics.PorterDuff.Mode getForegroundTintMode();
+ method @Deprecated @Nullable public android.graphics.PorterDuff.Mode getForegroundTintMode();
method public boolean getGlobalVisibleRect(android.graphics.Rect, android.graphics.Point);
method public final boolean getGlobalVisibleRect(android.graphics.Rect);
method public android.os.Handler getHandler();
@@ -50752,7 +50765,8 @@ package android.view {
method @Deprecated public void setBackgroundDrawable(android.graphics.drawable.Drawable);
method public void setBackgroundResource(@DrawableRes int);
method public void setBackgroundTintList(@Nullable android.content.res.ColorStateList);
- method public void setBackgroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
+ method @Deprecated public void setBackgroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
+ method public void setBackgroundTintMode(@Nullable android.graphics.BlendMode);
method public final void setBottom(int);
method public void setCameraDistance(float);
method public void setClickable(boolean);
@@ -50779,7 +50793,8 @@ package android.view {
method public void setForeground(android.graphics.drawable.Drawable);
method public void setForegroundGravity(int);
method public void setForegroundTintList(@Nullable android.content.res.ColorStateList);
- method public void setForegroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
+ method @Deprecated public void setForegroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
+ method public void setForegroundTintMode(@Nullable android.graphics.BlendMode);
method public void setHapticFeedbackEnabled(boolean);
method public void setHasTransientState(boolean);
method public void setHorizontalFadingEdgeEnabled(boolean);
@@ -52299,7 +52314,7 @@ package android.view.accessibility {
method public java.util.List getActionList();
method @Deprecated public int getActions();
method public java.util.List getAvailableExtraData();
- method public void getBoundsInParent(android.graphics.Rect);
+ method @Deprecated public void getBoundsInParent(android.graphics.Rect);
method public void getBoundsInScreen(android.graphics.Rect);
method public android.view.accessibility.AccessibilityNodeInfo getChild(int);
method public int getChildCount();
@@ -52368,7 +52383,7 @@ package android.view.accessibility {
method public boolean removeChild(android.view.View, int);
method public void setAccessibilityFocused(boolean);
method public void setAvailableExtraData(java.util.List);
- method public void setBoundsInParent(android.graphics.Rect);
+ method @Deprecated public void setBoundsInParent(android.graphics.Rect);
method public void setBoundsInScreen(android.graphics.Rect);
method public void setCanOpenPopup(boolean);
method public void setCheckable(boolean);
@@ -53048,6 +53063,16 @@ package android.view.autofill {
package android.view.contentcapture {
+ public final class ContentCaptureCondition implements android.os.Parcelable {
+ ctor public ContentCaptureCondition(@NonNull android.content.LocusId, int);
+ method public int describeContents();
+ method public int getFlags();
+ method @NonNull public android.content.LocusId getLocusId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator CREATOR;
+ field public static final int FLAG_IS_REGEX = 2; // 0x2
+ }
+
public final class ContentCaptureContext implements android.os.Parcelable {
method public int describeContents();
method @NonNull public static android.view.contentcapture.ContentCaptureContext forLocusId(@NonNull String);
@@ -53064,6 +53089,7 @@ package android.view.contentcapture {
}
public final class ContentCaptureManager {
+ method @Nullable public java.util.Set getContentCaptureConditions();
method @Nullable public android.content.ComponentName getServiceComponentName();
method public boolean isContentCaptureEnabled();
method public void removeUserData(@NonNull android.view.contentcapture.UserDataRemovalRequest);
diff --git a/api/system-current.txt b/api/system-current.txt
index a4cf10db3f4b7778fe138ca235aa2abf02345cff..b419851f85891f9fe827a86fbf32c090a828f9ae 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -49,6 +49,7 @@ package android {
field @Deprecated public static final String BROADCAST_NETWORK_PRIVILEGED = "android.permission.BROADCAST_NETWORK_PRIVILEGED";
field public static final String CAMERA_DISABLE_TRANSMIT_LED = "android.permission.CAMERA_DISABLE_TRANSMIT_LED";
field public static final String CAPTURE_AUDIO_HOTWORD = "android.permission.CAPTURE_AUDIO_HOTWORD";
+ field public static final String CAPTURE_MEDIA_OUTPUT = "android.permission.CAPTURE_MEDIA_OUTPUT";
field public static final String CAPTURE_TV_INPUT = "android.permission.CAPTURE_TV_INPUT";
field public static final String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
field public static final String CHANGE_DEVICE_IDLE_TEMP_WHITELIST = "android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST";
@@ -76,6 +77,7 @@ package android {
field public static final String HDMI_CEC = "android.permission.HDMI_CEC";
field public static final String HIDE_NON_SYSTEM_OVERLAY_WINDOWS = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS";
field public static final String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
+ field public static final String INSTALL_DYNAMIC_SYSTEM = "android.permission.INSTALL_DYNAMIC_SYSTEM";
field public static final String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS";
field public static final String INSTALL_PACKAGE_UPDATES = "android.permission.INSTALL_PACKAGE_UPDATES";
field public static final String INSTALL_SELF_UPDATES = "android.permission.INSTALL_SELF_UPDATES";
@@ -117,9 +119,11 @@ package android {
field public static final String MODIFY_PARENTAL_CONTROLS = "android.permission.MODIFY_PARENTAL_CONTROLS";
field public static final String MODIFY_QUIET_MODE = "android.permission.MODIFY_QUIET_MODE";
field public static final String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE";
+ field public static final String NETWORK_CARRIER_PROVISIONING = "android.permission.NETWORK_CARRIER_PROVISIONING";
field public static final String NETWORK_MANAGED_PROVISIONING = "android.permission.NETWORK_MANAGED_PROVISIONING";
field public static final String NETWORK_SCAN = "android.permission.NETWORK_SCAN";
field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
+ field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP";
field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -402,9 +406,9 @@ package android.app {
method public int describeContents();
method public long getBeginTimeMillis();
method public long getEndTimeMillis();
- method public int getUidCount();
+ method @IntRange(from=0) public int getUidCount();
method @Nullable public android.app.AppOpsManager.HistoricalUidOps getUidOps(int);
- method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(int);
+ method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(@IntRange(from=0) int);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
}
@@ -424,8 +428,8 @@ package android.app {
public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String);
- method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(int);
- method public int getOpCount();
+ method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(@IntRange(from=0) int);
+ method @IntRange(from=0) public int getOpCount();
method @NonNull public String getPackageName();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
@@ -433,9 +437,9 @@ package android.app {
public static final class AppOpsManager.HistoricalUidOps implements android.os.Parcelable {
method public int describeContents();
- method public int getPackageCount();
+ method @IntRange(from=0) public int getPackageCount();
method @Nullable public android.app.AppOpsManager.HistoricalPackageOps getPackageOps(@NonNull String);
- method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(int);
+ method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(@IntRange(from=0) int);
method public int getUid();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
@@ -491,12 +495,12 @@ package android.app {
ctor public InstantAppResolverService();
method public final void attachBaseContext(android.content.Context);
method public final android.os.IBinder onBind(android.content.Intent);
- method @Deprecated public void onGetInstantAppIntentFilter(int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
- method @Deprecated public void onGetInstantAppIntentFilter(android.content.Intent, int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
- method public void onGetInstantAppIntentFilter(android.content.Intent, int[], android.os.UserHandle, String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
- method @Deprecated public void onGetInstantAppResolveInfo(int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
- method @Deprecated public void onGetInstantAppResolveInfo(android.content.Intent, int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
- method public void onGetInstantAppResolveInfo(android.content.Intent, int[], android.os.UserHandle, String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ method @Deprecated public void onGetInstantAppIntentFilter(@Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ method @Deprecated public void onGetInstantAppIntentFilter(@NonNull android.content.Intent, @Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ method public void onGetInstantAppIntentFilter(@NonNull android.content.Intent, @Nullable int[], @NonNull android.os.UserHandle, @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ method @Deprecated public void onGetInstantAppResolveInfo(@Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ method @Deprecated public void onGetInstantAppResolveInfo(@NonNull android.content.Intent, @Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ method public void onGetInstantAppResolveInfo(@NonNull android.content.Intent, @Nullable int[], @NonNull android.os.UserHandle, @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
}
public static final class InstantAppResolverService.InstantAppResolutionCallback {
@@ -563,7 +567,7 @@ package android.app {
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
+ method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @NonNull public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setBroadcastSubscriber(android.app.PendingIntent, long, long) throws android.app.StatsManager.StatsUnavailableException;
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
@@ -1256,9 +1260,9 @@ package android.bluetooth {
public final class BluetoothDevice implements android.os.Parcelable {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean cancelBondProcess();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public String getMetadata(int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean getSilenceMode();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted();
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, String);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int);
@@ -1267,7 +1271,6 @@ package android.bluetooth {
field public static final int ACCESS_REJECTED = 2; // 0x2
field public static final int ACCESS_UNKNOWN = 0; // 0x0
field public static final String ACTION_SILENCE_MODE_CHANGED = "android.bluetooth.device.action.SILENCE_MODE_CHANGED";
- field public static final String EXTRA_SILENCE_ENABLED = "android.bluetooth.device.extra.SILENCE_ENABLED";
field public static final int METADATA_COMPANION_APP = 4; // 0x4
field public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16; // 0x10
field public static final int METADATA_HARDWARE_VERSION = 3; // 0x3
@@ -1456,14 +1459,14 @@ package android.content.om {
public final class OverlayInfo implements android.os.Parcelable {
method public int describeContents();
+ method @Nullable public String getCategory();
+ method @NonNull public String getPackageName();
+ method @Nullable public String getTargetOverlayableName();
+ method @Nullable public String getTargetPackageName();
+ method public int getUserId();
method public boolean isEnabled();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- field public final String category;
- field public final String packageName;
- field public final String targetOverlayableName;
- field public final String targetPackageName;
- field public final int userId;
}
public class OverlayManager {
@@ -1548,6 +1551,18 @@ package android.content.pm {
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
}
+ public class LauncherApps {
+ method @Nullable public android.content.pm.LauncherApps.AppUsageLimit getAppUsageLimit(@NonNull String, @NonNull android.os.UserHandle);
+ }
+
+ public static final class LauncherApps.AppUsageLimit implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getTotalUsageLimit();
+ method public long getUsageRemaining();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator CREATOR;
+ }
+
public class PackageInstaller {
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
}
@@ -1591,53 +1606,52 @@ package android.content.pm {
}
public abstract class PackageManager {
- method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
+ method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
method public abstract boolean arePermissionsIndividuallyControlled();
- method public abstract java.util.List getAllIntentFilters(String);
+ method @NonNull public abstract java.util.List getAllIntentFilters(@NonNull String);
method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.pm.ApplicationInfo getApplicationInfoAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public android.content.pm.dex.ArtManager getArtManager();
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_SHARED_LIBRARIES) public java.util.List getDeclaredSharedLibraries(@NonNull String, int);
- method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int);
+ method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int);
method @Nullable @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public CharSequence getHarmfulAppWarning(@NonNull String);
- method public String getIncidentReportApproverPackageName();
- method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract java.util.List getInstalledPackagesAsUser(int, int);
+ method @Nullable public String getIncidentReportApproverPackageName();
+ method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract java.util.List getInstalledPackagesAsUser(int, int);
method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_INSTANT_APPS) public abstract android.graphics.drawable.Drawable getInstantAppIcon(String);
- method public abstract android.content.ComponentName getInstantAppInstallerComponent();
- method public abstract android.content.ComponentName getInstantAppResolverSettingsComponent();
+ method @Nullable public abstract android.content.ComponentName getInstantAppInstallerComponent();
+ method @Nullable public abstract android.content.ComponentName getInstantAppResolverSettingsComponent();
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_INSTANT_APPS) public abstract java.util.List getInstantApps();
- method public abstract java.util.List getIntentFilterVerifications(String);
- method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract int getIntentVerificationStatusAsUser(String, int);
- method @android.content.pm.PackageManager.PermissionFlags @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS}) public abstract int getPermissionFlags(String, String, @NonNull android.os.UserHandle);
+ method @NonNull public abstract java.util.List getIntentFilterVerifications(@NonNull String);
+ method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract int getIntentVerificationStatusAsUser(@NonNull String, int);
+ method @android.content.pm.PackageManager.PermissionFlags @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
method @NonNull @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] getUnsuspendablePackages(@NonNull String[]);
method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
- method @Deprecated public abstract int installExistingPackage(String) throws android.content.pm.PackageManager.NameNotFoundException;
- method @Deprecated public abstract int installExistingPackage(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List queryBroadcastReceiversAsUser(android.content.Intent, int, android.os.UserHandle);
+ method @Deprecated public abstract int installExistingPackage(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @Deprecated public abstract int installExistingPackage(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List queryBroadcastReceiversAsUser(@NonNull android.content.Intent, int, android.os.UserHandle);
method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List queryIntentActivitiesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List queryIntentContentProvidersAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List queryIntentServicesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
- method public abstract void registerDexModule(String, @Nullable android.content.pm.PackageManager.DexModuleRegisterCallback);
- method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
+ method public abstract void registerDexModule(@NonNull String, @Nullable android.content.pm.PackageManager.DexModuleRegisterCallback);
+ method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
method @Deprecated public void replacePreferredActivity(@NonNull android.content.IntentFilter, int, @NonNull java.util.List, @NonNull android.content.ComponentName);
method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
method public void sendDeviceCustomizationReadyBroadcast();
- method @RequiresPermission(allOf={android.Manifest.permission.SET_PREFERRED_APPLICATIONS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public abstract boolean setDefaultBrowserPackageNameAsUser(String, int);
+ method @RequiresPermission(allOf={android.Manifest.permission.SET_PREFERRED_APPLICATIONS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public abstract boolean setDefaultBrowserPackageNameAsUser(@Nullable String, int);
method @NonNull @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setDistractingPackageRestrictions(@NonNull String[], int);
method @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public void setHarmfulAppWarning(@NonNull String, @Nullable CharSequence);
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable String);
method @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable android.content.pm.SuspendDialogInfo);
method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public void setSyntheticAppDetailsActivityEnabled(@NonNull String, boolean);
- method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public abstract void setUpdateAvailable(String, boolean);
- method @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public abstract boolean updateIntentVerificationStatusAsUser(String, int, int);
- method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(String, String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, java.util.List);
+ method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public abstract void setUpdateAvailable(@NonNull String, boolean);
+ method @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public abstract boolean updateIntentVerificationStatusAsUser(@NonNull String, int, int);
+ method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle);
+ method @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, @NonNull java.util.List);
field public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS";
field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES";
field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
field public static final String FEATURE_TELEPHONY_CARRIERLOCK = "android.hardware.telephony.carrierlock";
field public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 32; // 0x20
- field public static final int FLAG_PERMISSION_HIDDEN = 1024; // 0x400
field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40
field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8
@@ -1708,7 +1722,7 @@ package android.content.pm {
method public void onPermissionsChanged(int);
}
- @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags {
+ @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags {
}
public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -3376,19 +3390,19 @@ package android.location {
public class LocationManager {
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void flushGnssBatch();
+ method @Nullable public String getExtraLocationControllerPackage();
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int getGnssBatchSize();
method @Nullable public android.location.GnssCapabilities getGnssCapabilities();
- method @Nullable public String getLocationControllerExtraPackage();
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void injectGnssMeasurementCorrections(@NonNull android.location.GnssMeasurementCorrections);
- method public boolean isLocationControllerExtraPackageEnabled();
+ method public boolean isExtraLocationControllerPackageEnabled();
method public boolean isLocationEnabledForUser(@NonNull android.os.UserHandle);
method public boolean isProviderEnabledForUser(@NonNull String, @NonNull android.os.UserHandle);
method public boolean isProviderPackage(@NonNull String);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerGnssBatchedLocationCallback(long, boolean, @NonNull android.location.BatchedLocationCallback, @Nullable android.os.Handler);
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackage(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackageEnabled(boolean);
+ method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackage(@Nullable String);
+ method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackageEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser(@NonNull String, boolean, @NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean unregisterGnssBatchedLocationCallback(@NonNull android.location.BatchedLocationCallback);
@@ -3601,6 +3615,7 @@ package android.media.audiopolicy {
ctor public AudioMixingRule.Builder();
method public android.media.audiopolicy.AudioMixingRule.Builder addMixRule(int, Object) throws java.lang.IllegalArgumentException;
method public android.media.audiopolicy.AudioMixingRule.Builder addRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
+ method @NonNull public android.media.audiopolicy.AudioMixingRule.Builder allowPrivilegedPlaybackCapture(boolean);
method public android.media.audiopolicy.AudioMixingRule build();
method public android.media.audiopolicy.AudioMixingRule.Builder excludeMixRule(int, Object) throws java.lang.IllegalArgumentException;
method public android.media.audiopolicy.AudioMixingRule.Builder excludeRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
@@ -4058,7 +4073,7 @@ package android.net {
}
public final class IpPrefix implements android.os.Parcelable {
- ctor public IpPrefix(@NonNull java.net.InetAddress, int);
+ ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
ctor public IpPrefix(@NonNull String);
}
@@ -4079,8 +4094,8 @@ package android.net {
}
public class LinkAddress implements android.os.Parcelable {
- ctor public LinkAddress(java.net.InetAddress, int, int, int);
- ctor public LinkAddress(@NonNull java.net.InetAddress, int);
+ ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int);
+ ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
ctor public LinkAddress(@NonNull String);
ctor public LinkAddress(@NonNull String, int, int);
method public boolean isGlobalPreferred();
@@ -4144,7 +4159,7 @@ package android.net {
}
public static class NetworkRequest.Builder {
- method @NonNull public android.net.NetworkRequest.Builder setSignalStrength(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
}
public class NetworkScoreManager {
@@ -4233,6 +4248,10 @@ package android.net {
field public static final int TAG_SYSTEM_PROBE = -190; // 0xffffff42
}
+ public abstract class Uri implements java.lang.Comparable android.os.Parcelable {
+ method @NonNull public String toSafeString();
+ }
+
public class VpnService extends android.app.Service {
method @RequiresPermission(android.Manifest.permission.CONTROL_VPN) public static void prepareAndAuthorize(android.content.Context);
}
@@ -4257,8 +4276,8 @@ package android.net.apf {
public final class ApfCapabilities implements android.os.Parcelable {
ctor public ApfCapabilities(int, int, int);
method public int describeContents();
- method public static boolean getApfDrop8023Frames(@NonNull android.content.Context);
- method @NonNull public static int[] getApfEthTypeBlackList(@NonNull android.content.Context);
+ method public static boolean getApfDrop8023Frames();
+ method @NonNull public static int[] getApfEtherTypeBlackList();
method public boolean hasDataAccess();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
@@ -5643,12 +5662,12 @@ package android.os.image {
public class DynamicSystemClient {
ctor public DynamicSystemClient(@NonNull android.content.Context);
- method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void bind();
+ method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void bind();
method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
- method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long);
- method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long, long);
- method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void unbind();
+ method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void start(@NonNull android.net.Uri, long);
+ method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void start(@NonNull android.net.Uri, long, long);
+ method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void unbind();
field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6
field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4
field public static final int CAUSE_ERROR_IO = 3; // 0x3
@@ -5664,7 +5683,7 @@ package android.os.image {
}
public static interface DynamicSystemClient.OnStatusChangedListener {
- method public void onStatusChanged(int, int, long);
+ method public void onStatusChanged(int, int, long, @Nullable Throwable);
}
}
@@ -6048,6 +6067,7 @@ package android.provider {
field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
field public static final String ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS = "android.settings.LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS";
field public static final String ACTION_MANAGE_DOMAIN_URLS = "android.settings.MANAGE_DOMAIN_URLS";
+ field public static final String ACTION_MANAGE_MORE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_MORE_DEFAULT_APPS_SETTINGS";
field public static final String ACTION_NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS";
field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE";
field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS";
@@ -6444,6 +6464,7 @@ package android.service.contentcapture {
method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
method public void onDisconnected();
method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
+ method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set);
method public final void setContentCaptureWhitelist(@Nullable java.util.Set, @Nullable java.util.Set);
field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
field public static final String SERVICE_META_DATA = "android.content_capture";
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 9780d43624fa77a4a9ef5f49a85f4387efbf6b78..162f212a787eb11d7107b0eebd1757dabbcbf11a 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -67,6 +67,8 @@ package android.location {
method @Deprecated public boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
method @Deprecated public void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
method @Deprecated public void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackage(String);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackageEnabled(boolean);
}
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 9817a9747ff764071bd1850932270c72259bb0d5..cb2dc0715071577d4d3fad8469f6dcc82a158f42 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -238,9 +238,9 @@ package android.app {
method public int describeContents();
method public long getBeginTimeMillis();
method public long getEndTimeMillis();
- method public int getUidCount();
+ method @IntRange(from=0) public int getUidCount();
method @Nullable public android.app.AppOpsManager.HistoricalUidOps getUidOps(int);
- method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(int);
+ method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(@IntRange(from=0) int);
method public void increaseAccessCount(int, int, @NonNull String, int, int, long);
method public void increaseAccessDuration(int, int, @NonNull String, int, int, long);
method public void increaseRejectCount(int, int, @NonNull String, int, int, long);
@@ -264,8 +264,8 @@ package android.app {
public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String);
- method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(int);
- method public int getOpCount();
+ method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(@IntRange(from=0) int);
+ method @IntRange(from=0) public int getOpCount();
method @NonNull public String getPackageName();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
@@ -273,9 +273,9 @@ package android.app {
public static final class AppOpsManager.HistoricalUidOps implements android.os.Parcelable {
method public int describeContents();
- method public int getPackageCount();
+ method @IntRange(from=0) public int getPackageCount();
method @Nullable public android.app.AppOpsManager.HistoricalPackageOps getPackageOps(@NonNull String);
- method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(int);
+ method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(@IntRange(from=0) int);
method public int getUid();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
@@ -315,7 +315,9 @@ package android.app {
}
public final class NotificationChannel implements android.os.Parcelable {
+ method public boolean isImportanceLockedByCriticalDeviceFunction();
method public boolean isImportanceLockedByOEM();
+ method public void setImportanceLockedByCriticalDeviceFunction(boolean);
method public void setImportanceLockedByOEM(boolean);
}
@@ -661,26 +663,27 @@ package android.content.pm {
public abstract class PackageManager {
method public abstract boolean arePermissionsIndividuallyControlled();
- method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int);
- method public String getIncidentReportApproverPackageName();
- method public abstract int getInstallReason(String, @NonNull android.os.UserHandle);
- method public abstract java.util.List getInstalledApplicationsAsUser(int, int);
- method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract java.util.List getInstalledPackagesAsUser(int, int);
+ method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int);
+ method @Nullable public String getIncidentReportApproverPackageName();
+ method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle);
+ method @NonNull public abstract java.util.List getInstalledApplicationsAsUser(int, int);
+ method @NonNull @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract java.util.List getInstalledPackagesAsUser(int, int);
method @Nullable public abstract String[] getNamesForUids(int[]);
- method public abstract String getPermissionControllerPackageName();
- method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS", "android.permission.GET_RUNTIME_PERMISSIONS"}) public abstract int getPermissionFlags(String, String, @NonNull android.os.UserHandle);
+ method @NonNull public abstract String getPermissionControllerPackageName();
+ method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS", "android.permission.GET_RUNTIME_PERMISSIONS"}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
method @NonNull public abstract String getServicesSystemSharedLibraryPackageName();
method @NonNull public abstract String getSharedSystemSharedLibraryPackageName();
- method public String getWellbeingPackageName();
+ method @Nullable public String getWellbeingPackageName();
method @RequiresPermission("android.permission.GRANT_RUNTIME_PERMISSIONS") public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
- method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(String, String, int, int, @NonNull android.os.UserHandle);
+ method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, int, int, @NonNull android.os.UserHandle);
field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage";
field public static final String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption";
- field public static final int FLAG_PERMISSION_HIDDEN = 1024; // 0x400
+ field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40
field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8
field public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED = 128; // 0x80
+ field public static final int FLAG_PERMISSION_SYSTEM_FIXED = 16; // 0x10
field public static final int FLAG_PERMISSION_USER_FIXED = 2; // 0x2
field public static final int FLAG_PERMISSION_USER_SET = 1; // 0x1
field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
@@ -1237,7 +1240,7 @@ package android.net {
}
public final class IpPrefix implements android.os.Parcelable {
- ctor public IpPrefix(@NonNull java.net.InetAddress, int);
+ ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
ctor public IpPrefix(@NonNull String);
}
@@ -1246,8 +1249,8 @@ package android.net {
}
public class LinkAddress implements android.os.Parcelable {
- ctor public LinkAddress(java.net.InetAddress, int, int, int);
- ctor public LinkAddress(@NonNull java.net.InetAddress, int);
+ ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int);
+ ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
ctor public LinkAddress(@NonNull String);
ctor public LinkAddress(@NonNull String, int, int);
method public boolean isGlobalPreferred();
@@ -1356,8 +1359,8 @@ package android.net.apf {
public final class ApfCapabilities implements android.os.Parcelable {
ctor public ApfCapabilities(int, int, int);
method public int describeContents();
- method public static boolean getApfDrop8023Frames(@NonNull android.content.Context);
- method @NonNull public static int[] getApfEthTypeBlackList(@NonNull android.content.Context);
+ method public static boolean getApfDrop8023Frames();
+ method @NonNull public static int[] getApfEtherTypeBlackList();
method public boolean hasDataAccess();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
@@ -2457,6 +2460,7 @@ package android.service.contentcapture {
method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
method public void onDisconnected();
method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
+ method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set);
method public final void setContentCaptureWhitelist(@Nullable java.util.Set, @Nullable java.util.Set);
field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
field public static final String SERVICE_META_DATA = "android.content_capture";
@@ -2662,6 +2666,15 @@ package android.telephony {
method public void setVoiceRoamingType(int);
}
+ public final class SmsManager {
+ method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
+ field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
+ field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
+ field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
+ field public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4; // 0x4
+ field public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2; // 0x2
+ }
+
public class TelephonyManager {
method public int checkCarrierPrivilegesForPackage(String);
method public int getCarrierIdListVersion();
diff --git a/cmds/bmgr/Android.bp b/cmds/bmgr/Android.bp
new file mode 100644
index 0000000000000000000000000000000000000000..b64923bcbe1b177bb7295a36f59e3d4f0e568c84
--- /dev/null
+++ b/cmds/bmgr/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2007 The Android Open Source Project
+//
+
+java_binary {
+ name: "bmgr",
+ wrapper: "bmgr",
+ srcs: ["**/*.java"],
+}
diff --git a/cmds/bmgr/Android.mk b/cmds/bmgr/Android.mk
deleted file mode 100644
index d520cf2143ee6d02a8d9f8a8f3bfdded66568f52..0000000000000000000000000000000000000000
--- a/cmds/bmgr/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := bmgrlib
-LOCAL_MODULE_STEM := bmgr
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := bmgr
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_SRC_FILES := bmgr
-LOCAL_REQUIRED_MODULES := bmgrlib
-include $(BUILD_PREBUILT)
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index a6c7cae9bdb6cc1a751d43885d5ab5362139b916..8e7277c55ed8beb20d07a8b466fd31747dd06a23 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -101,7 +101,7 @@ static constexpr size_t TEXT_POS_LEN_MAX = 16;
BootAnimation::BootAnimation(sp callbacks)
: Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
- mTimeFormat12Hour(false), mTimeCheckThread(NULL), mCallbacks(callbacks) {
+ mTimeFormat12Hour(false), mTimeCheckThread(nullptr), mCallbacks(callbacks) {
mSession = new SurfaceComposerClient();
std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
@@ -156,7 +156,7 @@ void BootAnimation::binderDied(const wp&)
status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
const char* name) {
Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
- if (asset == NULL)
+ if (asset == nullptr)
return NO_INIT;
SkBitmap bitmap;
sk_sp data = SkData::MakeWithoutCopy(asset->getBuffer(false),
@@ -234,7 +234,7 @@ status_t BootAnimation::initTexture(FileMap* map, int* width, int* height)
case kN32_SkColorType:
if (!mUseNpotTextures && (tw != w || th != h)) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, 0);
+ GL_UNSIGNED_BYTE, nullptr);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
} else {
@@ -246,7 +246,7 @@ status_t BootAnimation::initTexture(FileMap* map, int* width, int* height)
case kRGB_565_SkColorType:
if (!mUseNpotTextures && (tw != w || th != h)) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
- GL_UNSIGNED_SHORT_5_6_5, 0);
+ GL_UNSIGNED_SHORT_5_6_5, nullptr);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
} else {
@@ -304,10 +304,10 @@ status_t BootAnimation::readyToRun() {
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(display, 0, 0);
+ eglInitialize(display, nullptr, nullptr);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
- surface = eglCreateWindowSurface(display, config, s.get(), NULL);
- context = eglCreateContext(display, config, NULL, NULL);
+ surface = eglCreateWindowSurface(display, config, s.get(), nullptr);
+ context = eglCreateContext(display, config, nullptr, nullptr);
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
@@ -671,7 +671,7 @@ bool BootAnimation::parseAnimationDesc(Animation& animation)
// Parse the description file
for (;;) {
const char* endl = strstr(s, "\n");
- if (endl == NULL) break;
+ if (endl == nullptr) break;
String8 line(s, endl - s);
const char* l = line.string();
int fps = 0;
@@ -699,8 +699,8 @@ bool BootAnimation::parseAnimationDesc(Animation& animation)
part.count = count;
part.pause = pause;
part.path = path;
- part.audioData = NULL;
- part.animation = NULL;
+ part.audioData = nullptr;
+ part.animation = nullptr;
if (!parseColor(color, part.backgroundColor)) {
SLOGE("> invalid color '#%s'", color);
part.backgroundColor[0] = 0.0f;
@@ -716,9 +716,9 @@ bool BootAnimation::parseAnimationDesc(Animation& animation)
part.playUntilComplete = false;
part.count = 1;
part.pause = 0;
- part.audioData = NULL;
+ part.audioData = nullptr;
part.animation = loadAnimation(String8(SYSTEM_BOOTANIMATION_FILE));
- if (part.animation != NULL)
+ if (part.animation != nullptr)
animation.parts.add(part);
}
s = ++endl;
@@ -731,7 +731,7 @@ bool BootAnimation::preloadZip(Animation& animation)
{
// read all the data structures
const size_t pcount = animation.parts.size();
- void *cookie = NULL;
+ void *cookie = nullptr;
ZipFileRO* zip = animation.zip;
if (!zip->startIteration(&cookie)) {
return false;
@@ -739,7 +739,7 @@ bool BootAnimation::preloadZip(Animation& animation)
ZipEntryRO entry;
char name[ANIM_ENTRY_NAME_MAX];
- while ((entry = zip->nextEntry(cookie)) != NULL) {
+ while ((entry = zip->nextEntry(cookie)) != nullptr) {
const int foundEntryName = zip->getEntryFileName(entry, name, ANIM_ENTRY_NAME_MAX);
if (foundEntryName > ANIM_ENTRY_NAME_MAX || foundEntryName == -1) {
SLOGE("Error fetching entry file name");
@@ -762,7 +762,7 @@ bool BootAnimation::preloadZip(Animation& animation)
if (path == animation.parts[j].path) {
uint16_t method;
// supports only stored png files
- if (zip->getEntryInfo(entry, &method, NULL, NULL, NULL, NULL, NULL)) {
+ if (zip->getEntryInfo(entry, &method, nullptr, nullptr, nullptr, nullptr, nullptr)) {
if (method == ZipFileRO::kCompressStored) {
FileMap* map = zip->createEntryFileMap(entry);
if (map) {
@@ -800,7 +800,7 @@ bool BootAnimation::preloadZip(Animation& animation)
for (size_t frameIdx = 0; frameIdx < part.frames.size(); frameIdx++) {
const char* endl = strstr(trimDataStr, "\n");
// No more trimData for this part.
- if (endl == NULL) {
+ if (endl == nullptr) {
break;
}
String8 line(trimDataStr, endl - trimDataStr);
@@ -927,7 +927,7 @@ bool BootAnimation::playAnimation(const Animation& animation)
glBindTexture(GL_TEXTURE_2D, 0);
// Handle animation package
- if (part.animation != NULL) {
+ if (part.animation != nullptr) {
playAnimation(*part.animation);
if (exitPending())
break;
@@ -1001,7 +1001,7 @@ bool BootAnimation::playAnimation(const Animation& animation)
spec.tv_nsec = (now + delay) % 1000000000;
int err;
do {
- err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
+ err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, nullptr);
} while (err<0 && errno == EINTR);
}
@@ -1090,13 +1090,13 @@ BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn)
if (mLoadedFiles.indexOf(fn) >= 0) {
SLOGE("File \"%s\" is already loaded. Cyclic ref is not allowed",
fn.string());
- return NULL;
+ return nullptr;
}
ZipFileRO *zip = ZipFileRO::open(fn);
- if (zip == NULL) {
+ if (zip == nullptr) {
SLOGE("Failed to open animation zip \"%s\": %s",
fn.string(), strerror(errno));
- return NULL;
+ return nullptr;
}
Animation *animation = new Animation;
@@ -1107,7 +1107,7 @@ BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn)
parseAnimationDesc(*animation);
if (!preloadZip(*animation)) {
- return NULL;
+ return nullptr;
}
@@ -1135,7 +1135,7 @@ bool BootAnimation::updateIsTimeAccurate() {
}
FILE* file = fopen(LAST_TIME_CHANGED_FILE_PATH, "r");
- if (file != NULL) {
+ if (file != nullptr) {
long long lastChangedTime = 0;
fscanf(file, "%lld", &lastChangedTime);
fclose(file);
diff --git a/cmds/bootanimation/audioplay.cpp b/cmds/bootanimation/audioplay.cpp
index 874aab08862ed7e0dbf9306910c68fdbeace02a4..c5e16c6b7deb68ccf51d8e73c4600dfee911c69b 100644
--- a/cmds/bootanimation/audioplay.cpp
+++ b/cmds/bootanimation/audioplay.cpp
@@ -39,14 +39,14 @@ namespace {
using namespace android;
// engine interfaces
-static SLObjectItf engineObject = NULL;
+static SLObjectItf engineObject = nullptr;
static SLEngineItf engineEngine;
// output mix interfaces
-static SLObjectItf outputMixObject = NULL;
+static SLObjectItf outputMixObject = nullptr;
// buffer queue player interfaces
-static SLObjectItf bqPlayerObject = NULL;
+static SLObjectItf bqPlayerObject = nullptr;
static SLPlayItf bqPlayerPlay;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
static SLMuteSoloItf bqPlayerMuteSolo;
@@ -89,7 +89,7 @@ void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
}
bool hasPlayer() {
- return (engineObject != NULL && bqPlayerObject != NULL);
+ return (engineObject != nullptr && bqPlayerObject != nullptr);
}
// create the engine and output mix objects
@@ -97,7 +97,7 @@ bool createEngine() {
SLresult result;
// create engine
- result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
+ result = slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
if (result != SL_RESULT_SUCCESS) {
ALOGE("slCreateEngine failed with result %d", result);
return false;
@@ -121,7 +121,7 @@ bool createEngine() {
(void)result;
// create output mix
- result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
+ result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, nullptr, nullptr);
if (result != SL_RESULT_SUCCESS) {
ALOGE("sl engine CreateOutputMix failed with result %d", result);
return false;
@@ -173,7 +173,7 @@ bool createBufferQueueAudioPlayer(const ChunkFormat* chunkFormat) {
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
- SLDataSink audioSnk = {&loc_outmix, NULL};
+ SLDataSink audioSnk = {&loc_outmix, nullptr};
// create audio player
const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME, SL_IID_ANDROIDCONFIGURATION};
@@ -236,7 +236,7 @@ bool createBufferQueueAudioPlayer(const ChunkFormat* chunkFormat) {
(void)result;
// register callback on the buffer queue
- result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
+ result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, nullptr);
if (result != SL_RESULT_SUCCESS) {
ALOGE("sl bqPlayerBufferQueue RegisterCallback failed with result %d", result);
return false;
@@ -261,7 +261,7 @@ bool parseClipBuf(const uint8_t* clipBuf, int clipBufSize, const ChunkFormat** o
const uint8_t** oSoundBuf, unsigned* oSoundBufSize) {
*oSoundBuf = clipBuf;
*oSoundBufSize = clipBufSize;
- *oChunkFormat = NULL;
+ *oChunkFormat = nullptr;
const RiffWaveHeader* wavHeader = (const RiffWaveHeader*)*oSoundBuf;
if (*oSoundBufSize < sizeof(*wavHeader) || (wavHeader->riff_id != ID_RIFF) ||
(wavHeader->wave_id != ID_WAVE)) {
@@ -303,7 +303,7 @@ bool parseClipBuf(const uint8_t* clipBuf, int clipBufSize, const ChunkFormat** o
}
}
- if (*oChunkFormat == NULL) {
+ if (*oChunkFormat == nullptr) {
ALOGE("format not found in WAV file");
return false;
}
@@ -435,7 +435,7 @@ void setPlaying(bool isPlaying) {
SLresult result;
- if (NULL != bqPlayerPlay) {
+ if (nullptr != bqPlayerPlay) {
// set the player's state
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay,
isPlaying ? SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_STOPPED);
@@ -445,28 +445,28 @@ void setPlaying(bool isPlaying) {
void destroy() {
// destroy buffer queue audio player object, and invalidate all associated interfaces
- if (bqPlayerObject != NULL) {
+ if (bqPlayerObject != nullptr) {
CHATTY("destroying audio player");
(*bqPlayerObject)->Destroy(bqPlayerObject);
- bqPlayerObject = NULL;
- bqPlayerPlay = NULL;
- bqPlayerBufferQueue = NULL;
- bqPlayerMuteSolo = NULL;
- bqPlayerVolume = NULL;
+ bqPlayerObject = nullptr;
+ bqPlayerPlay = nullptr;
+ bqPlayerBufferQueue = nullptr;
+ bqPlayerMuteSolo = nullptr;
+ bqPlayerVolume = nullptr;
}
// destroy output mix object, and invalidate all associated interfaces
- if (outputMixObject != NULL) {
+ if (outputMixObject != nullptr) {
(*outputMixObject)->Destroy(outputMixObject);
- outputMixObject = NULL;
+ outputMixObject = nullptr;
}
// destroy engine object, and invalidate all associated interfaces
- if (engineObject != NULL) {
+ if (engineObject != nullptr) {
CHATTY("destroying audio engine");
(*engineObject)->Destroy(engineObject);
- engineObject = NULL;
- engineEngine = NULL;
+ engineObject = nullptr;
+ engineEngine = nullptr;
}
}
diff --git a/cmds/bootanimation/iot/iotbootanimation_main.cpp b/cmds/bootanimation/iot/iotbootanimation_main.cpp
index 2a3d3766ab38a14bb8e617d580651163f45e486d..ae3529796b9af84a5168da0c5513e54e43ae07e8 100644
--- a/cmds/bootanimation/iot/iotbootanimation_main.cpp
+++ b/cmds/bootanimation/iot/iotbootanimation_main.cpp
@@ -60,7 +60,7 @@ public:
mBootAction = new BootAction();
if (!mBootAction->init(library_path, mBootParameters)) {
- mBootAction = NULL;
+ mBootAction = nullptr;
}
};
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index d757e4611158a2d487c758e1a33fc3dcfeb7a28c..18d56fa87ccab1d389d4a5c7b4e7dfdbe6b44f50 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -84,6 +84,7 @@ cc_test {
"-readability-magic-numbers",
],
host_supported: true,
+ test_suites: ["general-tests"],
srcs: [
"tests/BinaryStreamVisitorTests.cpp",
"tests/CommandLineOptionsTests.cpp",
diff --git a/cmds/incident/Android.bp b/cmds/incident/Android.bp
index 2a5ec5bfacafc6d06d48573dee0b470310cdb406..f56f101465eb0b0f7e04b7c9b7a31091468aae12 100644
--- a/cmds/incident/Android.bp
+++ b/cmds/incident/Android.bp
@@ -29,6 +29,10 @@ cc_binary {
"libincident",
],
+ static_libs: [
+ "libplatformprotos",
+ ],
+
cflags: [
"-Wall",
"-Werror",
diff --git a/cmds/incident/main.cpp b/cmds/incident/main.cpp
index cdec6a01d086d80f489c0ebeacdab173dfd9f060..93e592c9c01b9e93315678063ca8327be92b3c88 100644
--- a/cmds/incident/main.cpp
+++ b/cmds/incident/main.cpp
@@ -68,6 +68,7 @@ Status
StatusListener::onReportSectionStatus(int32_t section, int32_t status)
{
fprintf(stderr, "section %d status %d\n", section, status);
+ ALOGD("section %d status %d\n", section, status);
return Status::ok();
}
@@ -75,6 +76,7 @@ Status
StatusListener::onReportServiceStatus(const String16& service, int32_t status)
{
fprintf(stderr, "service '%s' status %d\n", String8(service).string(), status);
+ ALOGD("service '%s' status %d\n", String8(service).string(), status);
return Status::ok();
}
@@ -82,6 +84,7 @@ Status
StatusListener::onReportFinished()
{
fprintf(stderr, "done\n");
+ ALOGD("done\n");
exit(0);
return Status::ok();
}
@@ -90,6 +93,7 @@ Status
StatusListener::onReportFailed()
{
fprintf(stderr, "failed\n");
+ ALOGD("failed\n");
exit(1);
return Status::ok();
}
@@ -146,24 +150,49 @@ find_section(const char* name)
// ================================================================================
static int
-get_dest(const char* arg)
+get_privacy_policy(const char* arg)
{
if (strcmp(arg, "L") == 0
|| strcmp(arg, "LOCAL") == 0) {
- return DEST_LOCAL;
+ return PRIVACY_POLICY_LOCAL;
}
if (strcmp(arg, "E") == 0
|| strcmp(arg, "EXPLICIT") == 0) {
- return DEST_EXPLICIT;
+ return PRIVACY_POLICY_EXPLICIT;
}
if (strcmp(arg, "A") == 0
|| strcmp(arg, "AUTO") == 0
|| strcmp(arg, "AUTOMATIC") == 0) {
- return DEST_AUTOMATIC;
+ return PRIVACY_POLICY_AUTOMATIC;
}
return -1; // return the default value
}
+// ================================================================================
+static bool
+parse_receiver_arg(const string& arg, string* pkg, string* cls)
+{
+ if (arg.length() == 0) {
+ return true;
+ }
+ size_t slash = arg.find('/');
+ if (slash == string::npos) {
+ return false;
+ }
+ if (slash == 0 || slash == arg.length() - 1) {
+ return false;
+ }
+ if (arg.find('/', slash+1) != string::npos) {
+ return false;
+ }
+ pkg->assign(arg, 0, slash);
+ cls->assign(arg, slash+1);
+ if ((*cls)[0] == '.') {
+ *cls = (*pkg) + (*cls);
+ }
+ return true;
+}
+
// ================================================================================
static void
usage(FILE* out)
@@ -173,10 +202,13 @@ usage(FILE* out)
fprintf(out, "Takes an incident report.\n");
fprintf(out, "\n");
fprintf(out, "OPTIONS\n");
+ fprintf(out, " -l list available sections\n");
+ fprintf(out, " -p privacy spec, LOCAL, EXPLICIT or AUTOMATIC. Default AUTOMATIC.\n");
+ fprintf(out, "\n");
+ fprintf(out, "and one of these destinations:\n");
fprintf(out, " -b (default) print the report to stdout (in proto format)\n");
fprintf(out, " -d send the report into dropbox\n");
- fprintf(out, " -l list available sections\n");
- fprintf(out, " -p privacy spec, LOCAL, EXPLICIT or AUTOMATIC\n");
+ fprintf(out, " -s PKG/CLS send broadcast to the broadcast receiver.\n");
fprintf(out, "\n");
fprintf(out, " SECTION the field numbers of the incident report fields to include\n");
fprintf(out, "\n");
@@ -187,12 +219,13 @@ main(int argc, char** argv)
{
Status status;
IncidentReportArgs args;
- enum { DEST_DROPBOX, DEST_STDOUT } destination = DEST_STDOUT;
- int dest = -1; // default
+ enum { DEST_UNSET, DEST_DROPBOX, DEST_STDOUT, DEST_BROADCAST } destination = DEST_UNSET;
+ int privacyPolicy = PRIVACY_POLICY_AUTOMATIC;
+ string receiverArg;
// Parse the args
int opt;
- while ((opt = getopt(argc, argv, "bhdlp:")) != -1) {
+ while ((opt = getopt(argc, argv, "bhdlp:s:")) != -1) {
switch (opt) {
case 'h':
usage(stdout);
@@ -201,13 +234,29 @@ main(int argc, char** argv)
section_list(stdout);
return 0;
case 'b':
+ if (!(destination == DEST_UNSET || destination == DEST_STDOUT)) {
+ usage(stderr);
+ return 1;
+ }
destination = DEST_STDOUT;
break;
case 'd':
+ if (!(destination == DEST_UNSET || destination == DEST_DROPBOX)) {
+ usage(stderr);
+ return 1;
+ }
destination = DEST_DROPBOX;
break;
case 'p':
- dest = get_dest(optarg);
+ privacyPolicy = get_privacy_policy(optarg);
+ break;
+ case 's':
+ if (destination != DEST_UNSET) {
+ usage(stderr);
+ return 1;
+ }
+ destination = DEST_BROADCAST;
+ receiverArg = optarg;
break;
default:
usage(stderr);
@@ -215,6 +264,17 @@ main(int argc, char** argv)
}
}
+ string pkg;
+ string cls;
+ if (parse_receiver_arg(receiverArg, &pkg, &cls)) {
+ args.setReceiverPkg(pkg);
+ args.setReceiverCls(cls);
+ } else {
+ fprintf(stderr, "badly formatted -s package/class option: %s\n\n", receiverArg.c_str());
+ usage(stderr);
+ return 1;
+ }
+
if (optind == argc) {
args.setAll(true);
} else {
@@ -236,7 +296,7 @@ main(int argc, char** argv)
}
}
}
- args.setDest(dest);
+ args.setPrivacyPolicy(privacyPolicy);
// Start the thread pool.
sp ps(ProcessState::self());
@@ -272,12 +332,17 @@ main(int argc, char** argv)
//IPCThreadState::self()->joinThreadPool();
while (true) {
- int amt = splice(fds[0], NULL, STDOUT_FILENO, NULL, 4096, 0);
- fprintf(stderr, "spliced %d bytes\n", amt);
+ uint8_t buf[4096];
+ ssize_t amt = TEMP_FAILURE_RETRY(read(fds[0], buf, sizeof(buf)));
if (amt < 0) {
- return errno;
+ break;
} else if (amt == 0) {
- return 0;
+ break;
+ }
+
+ ssize_t wamt = TEMP_FAILURE_RETRY(write(STDOUT_FILENO, buf, amt));
+ if (wamt != amt) {
+ return errno;
}
}
} else {
diff --git a/cmds/incidentd/Android.bp b/cmds/incidentd/Android.bp
index 3dc10939fed75c1801c1ea6a2ab4f3c076c4cf11..8f9a5f848668ab8ac970704f2c972132b9ba27ff 100644
--- a/cmds/incidentd/Android.bp
+++ b/cmds/incidentd/Android.bp
@@ -21,6 +21,7 @@ cc_binary {
srcs: [
"src/**/*.cpp",
+ "src/**/*.proto",
":incidentd_section_list",
],
@@ -43,6 +44,10 @@ cc_binary {
local_include_dirs: ["src"],
generated_headers: ["gen-platform-proto-constants"],
+ proto: {
+ type: "lite",
+ },
+
shared_libs: [
"libbase",
"libbinder",
@@ -56,6 +61,18 @@ cc_binary {
"libprotobuf-cpp-lite",
],
+ static_libs: [
+ "libincidentcompanion",
+ "libplatformprotos",
+ ],
+
+ product_variables: {
+ debuggable: {
+ cflags: ["-DALLOW_RESTRICTED_SECTIONS=1"],
+ },
+ },
+
+
init_rc: ["incidentd.rc"],
}
@@ -72,6 +89,7 @@ cc_test {
"-Wall",
"-Wno-unused-variable",
"-Wunused-parameter",
+ "-g",
// Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed.
"-Wno-error=implicit-fallthrough",
@@ -82,21 +100,26 @@ cc_test {
srcs: [
"tests/**/*.cpp",
- "src/PrivacyBuffer.cpp",
+ "tests/**/*.proto",
"src/FdBuffer.cpp",
"src/Privacy.cpp",
+ "src/PrivacyFilter.cpp",
"src/Reporter.cpp",
"src/Section.cpp",
"src/Throttler.cpp",
+ "src/WorkDirectory.cpp",
"src/incidentd_util.cpp",
+ "src/proto_util.cpp",
"src/report_directory.cpp",
+ "src/**/*.proto",
],
data: ["testdata/**/*"],
static_libs: [
"libgmock",
- "libplatformprotos",
+ "libincidentcompanion",
+ "libplatformprotos-test",
],
shared_libs: [
"libbase",
@@ -105,11 +128,19 @@ cc_test {
"libdumputils",
"libincident",
"liblog",
- "libprotobuf-cpp-lite",
+ "libprotobuf-cpp-full",
"libprotoutil",
"libservices",
"libutils",
],
+
+ target: {
+ android: {
+ proto: {
+ type: "full",
+ },
+ },
+ },
}
genrule {
diff --git a/cmds/incidentd/src/Broadcaster.cpp b/cmds/incidentd/src/Broadcaster.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..39e5393e1f81c869a84f152daa36018654b4c8d8
--- /dev/null
+++ b/cmds/incidentd/src/Broadcaster.cpp
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "Log.h"
+
+#include "Broadcaster.h"
+
+#include "IncidentService.h"
+
+#include
+#include
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using android::os::IIncidentCompanion;
+using binder::Status;
+
+// ============================================================
+Broadcaster::ConsentListener::ConsentListener(const sp& broadcaster,
+ const ReportId& reportId)
+ :mBroadcaster(broadcaster),
+ mId(reportId) {
+}
+
+Broadcaster::ConsentListener::~ConsentListener() {
+}
+
+Status Broadcaster::ConsentListener::onReportApproved() {
+ mBroadcaster->report_approved(mId);
+ return Status::ok();
+}
+
+Status Broadcaster::ConsentListener::onReportDenied() {
+ mBroadcaster->report_denied(mId);
+ return Status::ok();
+}
+
+// ============================================================
+Broadcaster::ReportId::ReportId()
+ :id(),
+ pkg(),
+ cls() {
+}
+
+Broadcaster::ReportId::ReportId(const ReportId& that)
+ :id(that.id),
+ pkg(that.pkg),
+ cls(that.cls) {
+}
+
+Broadcaster::ReportId::ReportId(const string& i, const string& p, const string& c)
+ :id(i),
+ pkg(p),
+ cls(c) {
+}
+
+Broadcaster::ReportId::~ReportId() {
+}
+
+bool Broadcaster::ReportId::operator<(const ReportId& that) const {
+ if (id < that.id) {
+ return true;
+ }
+ if (id > that.id) {
+ return false;
+ }
+ if (pkg < that.pkg) {
+ return true;
+ }
+ if (pkg > that.pkg) {
+ return false;
+ }
+ if (cls < that.cls) {
+ return true;
+ }
+ return false;
+}
+
+// ============================================================
+Broadcaster::ReportStatus::ReportStatus()
+ :approval_sent(false),
+ ready_sent(false),
+ listener(nullptr) {
+}
+
+Broadcaster::ReportStatus::ReportStatus(const ReportStatus& that)
+ :approval_sent(that.approval_sent),
+ ready_sent(that.ready_sent),
+ listener(that.listener) {
+}
+
+Broadcaster::ReportStatus::~ReportStatus() {
+}
+
+// ============================================================
+Broadcaster::Broadcaster(const sp& workDirectory)
+ :mReportHandler(),
+ mWorkDirectory(workDirectory) {
+}
+
+void Broadcaster::setHandler(const sp& handler) {
+ mReportHandler = handler;
+}
+
+void Broadcaster::reset() {
+ unique_lock lock(mLock);
+ mLastSent = 0;
+ mHistory.clear();
+ // Could cancel the listeners, but this happens when
+ // the system process crashes, so don't bother.
+}
+
+void Broadcaster::clearBroadcasts(const string& pkg, const string& cls, const string& id) {
+ unique_lock lock(mLock);
+
+ map::const_iterator found = mHistory.find(ReportId(id, pkg, cls));
+ if (found != mHistory.end()) {
+ if (found->second.listener != nullptr) {
+ sp ics = get_incident_companion();
+ if (ics != nullptr) {
+ ics->cancelAuthorization(found->second.listener);
+ }
+ }
+ mHistory.erase(found);
+ }
+}
+
+void Broadcaster::clearPackageBroadcasts(const string& pkg) {
+ unique_lock lock(mLock);
+
+ map::iterator it = mHistory.begin();
+ while (it != mHistory.end()) {
+ if (it->first.pkg == pkg) {
+ if (it->second.listener != nullptr) {
+ sp ics = get_incident_companion();
+ if (ics != nullptr) {
+ ics->cancelAuthorization(it->second.listener);
+ }
+ }
+ it = mHistory.erase(it);
+ } else {
+ it++;
+ }
+ }
+}
+
+Broadcaster::broadcast_status_t Broadcaster::sendBroadcasts() {
+ int err;
+ int64_t lastSent = get_last_sent();
+
+ vector> files;
+ mWorkDirectory->getReports(&files, 0); //lastSent);
+
+ // Don't send multiple broadcasts to the same receiver.
+ set reportReadyBroadcasts;
+
+ for (const sp& file: files) {
+ err = file->loadEnvelope();
+ if (err != NO_ERROR) {
+ ALOGW("Error (%s) loading envelope from %s", strerror(-err),
+ file->getEnvelopeFileName().c_str());
+ continue;
+ }
+
+ const ReportFileProto& envelope = file->getEnvelope();
+
+ if (!envelope.completed()) {
+ ALOGI("Incident report not completed skipping it: %s",
+ file->getEnvelopeFileName().c_str());
+ continue;
+ }
+
+ // When one of the broadcast functions in this loop fails, it's almost
+ // certainly because the system process is crashing or has crashed. Rather
+ // than continuing to pound on the system process and potentially make things
+ // worse, we bail right away, return BROADCASTS_BACKOFF, and we will try
+ // again later. In the meantime, if the system process did crash, it might
+ // clear out mHistory, which means we'll be back here again to send the
+ // backlog.
+ size_t reportCount = envelope.report_size();
+ bool hasApprovalPending = false;
+ for (int reportIndex = 0; reportIndex < reportCount; reportIndex++) {
+
+ const ReportFileProto_Report& report = envelope.report(reportIndex);
+ status_t err;
+ if (report.privacy_policy() == PRIVACY_POLICY_AUTOMATIC || report.share_approved()) {
+ // It's privacy policy is AUTO, or it's been approved,
+ // so send the actual broadcast.
+ if (!was_ready_sent(file->getId(), report.pkg(), report.cls())) {
+ if (report.pkg() == DROPBOX_SENTINEL.getPackageName()
+ && report.cls() == DROPBOX_SENTINEL.getClassName()) {
+ IncidentReportArgs args;
+ get_args_from_report(&args, report);
+ err = send_to_dropbox(file, args);
+ if (err != NO_ERROR) {
+ return BROADCASTS_BACKOFF;
+ }
+ } else {
+ reportReadyBroadcasts.insert(ReportId(file->getId(), report.pkg(),
+ report.cls()));
+ }
+ }
+ } else {
+ // It's not approved yet, so send the approval.
+ if (!was_approval_sent(file->getId(), report.pkg(), report.cls())) {
+ err = send_approval_broadcasts(file->getId(), report.pkg(), report.cls());
+ if (err != NO_ERROR) {
+ return BROADCASTS_BACKOFF;
+ }
+ hasApprovalPending = true;
+ }
+ }
+ }
+
+ lastSent = file->getTimestampNs();
+ if (!hasApprovalPending) {
+ set_last_sent(lastSent);
+ }
+ }
+
+ for (const ReportId& report: reportReadyBroadcasts) {
+ err = send_report_ready_broadcasts(report.id, report.pkg, report.cls);
+ if (err != NO_ERROR) {
+ return BROADCASTS_BACKOFF;
+ }
+ }
+
+ return mWorkDirectory->hasMore(lastSent) ? BROADCASTS_REPEAT : BROADCASTS_FINISHED;
+}
+
+void Broadcaster::set_last_sent(int64_t timestamp) {
+ unique_lock lock(mLock);
+ mLastSent = timestamp;
+}
+
+int64_t Broadcaster::get_last_sent() {
+ unique_lock lock(mLock);
+ return mLastSent;
+}
+
+/*
+void Broadcaster::printReportStatuses() const {
+ ALOGD("mHistory {");
+ for (map::const_iterator it = mHistory.begin();
+ it != mHistory.end(); it++) {
+ ALOGD(" [%s %s] --> [%d %d]", it->first.id.c_str(), it->first.pkg.c_str(),
+ it->second.approval_sent, it->second.ready_sent);
+ }
+ ALOGD("}");
+}
+*/
+
+bool Broadcaster::was_approval_sent(const string& id, const string& pkg, const string& cls) {
+ unique_lock lock(mLock);
+ map::const_iterator found = mHistory.find(ReportId(id, pkg, cls));
+ if (found != mHistory.end()) {
+ return found->second.approval_sent;
+ }
+ return false;
+}
+
+void Broadcaster::set_approval_sent(const string& id, const string& pkg, const string& cls,
+ const sp& listener) {
+ unique_lock lock(mLock);
+ ReportStatus& reportStatus = mHistory[ReportId(id, pkg, cls)];
+ reportStatus.approval_sent = true;
+ reportStatus.listener = listener;
+}
+
+bool Broadcaster::was_ready_sent(const string& id, const string& pkg, const string& cls) {
+ unique_lock lock(mLock);
+ map::const_iterator found = mHistory.find(ReportId(id, pkg, cls));
+ if (found != mHistory.end()) {
+ return found->second.ready_sent;
+ }
+ return false;
+}
+
+void Broadcaster::set_ready_sent(const string& id, const string& pkg, const string& cls) {
+ unique_lock lock(mLock);
+ mHistory[ReportId(id, pkg, cls)].ready_sent = true;
+}
+
+status_t Broadcaster::send_approval_broadcasts(const string& id, const string& pkg,
+ const string& cls) {
+ sp ics = get_incident_companion();
+ if (ics == nullptr) {
+ return NAME_NOT_FOUND;
+ }
+
+ sp listener = new ConsentListener(this, ReportId(id, pkg, cls));
+
+ ALOGI("send_approval_broadcasts for %s %s/%s", id.c_str(), pkg.c_str(), cls.c_str());
+
+ Status status = ics->authorizeReport(0, String16(pkg.c_str()),
+ String16(cls.c_str()), String16(id.c_str()), 0, listener);
+
+ if (!status.isOk()) {
+ // authorizeReport is oneway, so any error is a transaction error.
+ return status.transactionError();
+ }
+
+ set_approval_sent(id, pkg, cls, listener);
+
+ return NO_ERROR;
+}
+
+void Broadcaster::report_approved(const ReportId& reportId) {
+ status_t err;
+
+ // Kick off broadcaster to do send the ready broadcasts.
+ ALOGI("The user approved the report, so kicking off another broadcast pass. %s %s/%s",
+ reportId.id.c_str(), reportId.pkg.c_str(), reportId.cls.c_str());
+ sp file = mWorkDirectory->getReport(reportId.pkg, reportId.cls, reportId.id,
+ nullptr);
+ if (file != nullptr) {
+ err = file->loadEnvelope();
+ if (err != NO_ERROR) {
+ return;
+ }
+
+ err = file->markApproved(reportId.pkg, reportId.cls);
+ if (err != NO_ERROR) {
+ ALOGI("Couldn't find report that was just approved: %s %s/%s",
+ reportId.id.c_str(), reportId.pkg.c_str(), reportId.cls.c_str());
+ return;
+ }
+
+ file->saveEnvelope();
+ if (err != NO_ERROR) {
+ return;
+ }
+ }
+ mReportHandler->scheduleSendBacklog();
+}
+
+void Broadcaster::report_denied(const ReportId& reportId) {
+ // The user didn't approve the report, so remove it from the WorkDirectory.
+ ALOGI("The user denied the report, so deleting it. %s %s/%s",
+ reportId.id.c_str(), reportId.pkg.c_str(), reportId.cls.c_str());
+ sp file = mWorkDirectory->getReport(reportId.pkg, reportId.cls, reportId.id,
+ nullptr);
+ if (file != nullptr) {
+ mWorkDirectory->commit(file, reportId.pkg, reportId.cls);
+ }
+}
+
+status_t Broadcaster::send_report_ready_broadcasts(const string& id, const string& pkg,
+ const string& cls) {
+ sp ics = get_incident_companion();
+ if (ics == nullptr) {
+ return NAME_NOT_FOUND;
+ }
+
+ ALOGI("send_report_ready_broadcasts for %s %s/%s", id.c_str(), pkg.c_str(), cls.c_str());
+
+ Status status = ics->sendReportReadyBroadcast(String16(pkg.c_str()), String16(cls.c_str()));
+
+ if (!status.isOk()) {
+ // sendReportReadyBroadcast is oneway, so any error is a transaction error.
+ return status.transactionError();
+ }
+
+ set_ready_sent(id, pkg, cls);
+
+ return NO_ERROR;
+}
+
+status_t Broadcaster::send_to_dropbox(const sp& file,
+ const IncidentReportArgs& args) {
+ status_t err;
+
+ sp dropbox = new DropBoxManager();
+ if (dropbox == nullptr) {
+ ALOGW("Can't reach dropbox now, so we won't be able to write the incident report to there");
+ return NO_ERROR;
+ }
+
+ // Start a thread to write the data to dropbox.
+ int readFd = -1;
+ err = file->startFilteringData(&readFd, args);
+ if (err != NO_ERROR) {
+ return err;
+ }
+
+ // Takes ownership of readFd.
+ Status status = dropbox->addFile(String16("incident"), readFd, 0);
+ if (!status.isOk()) {
+ // TODO: This may or may not leak the readFd, depending on where it failed.
+ // Not sure how to fix this given the dropbox API.
+ ALOGW("Error sending incident report to dropbox.");
+ return -errno;
+ }
+
+ // On successful write, tell the working directory that this file is done.
+ mWorkDirectory->commit(file, DROPBOX_SENTINEL.getPackageName(),
+ DROPBOX_SENTINEL.getClassName());
+
+ // Don't need to call set_ready_sent, because we just removed it from the ReportFile,
+ // so we'll never hear about it again.
+
+ return NO_ERROR;
+}
+
+sp Broadcaster::get_incident_companion() {
+ sp binder = defaultServiceManager()->getService(String16("incidentcompanion"));
+ if (binder == nullptr) {
+ ALOGI("Can not find IIncidentCompanion service to send broadcast. Will try again later.");
+ return nullptr;
+ }
+
+ sp ics = interface_cast(binder);
+ if (ics == nullptr) {
+ ALOGI("The incidentcompanion service is not an IIncidentCompanion. Will try again later.");
+ return nullptr;
+ }
+
+ return ics;
+}
+
+} // namespace incidentd
+} // namespace os
+} // namespace android
+
+
diff --git a/cmds/incidentd/src/Broadcaster.h b/cmds/incidentd/src/Broadcaster.h
new file mode 100644
index 0000000000000000000000000000000000000000..933029709fb6b0caf86c8f488afe9865c6c3a895
--- /dev/null
+++ b/cmds/incidentd/src/Broadcaster.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+#pragma once
+
+#include "WorkDirectory.h"
+
+#include
+#include
+#include
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using android::binder::Status;
+using android::os::BnIncidentAuthListener;
+using android::os::IIncidentCompanion;
+
+class ReportHandler;
+
+class Broadcaster : public virtual RefBase {
+public:
+ enum broadcast_status_t {
+ BROADCASTS_FINISHED = 0,
+ BROADCASTS_REPEAT = 1,
+ BROADCASTS_BACKOFF = 2
+ };
+
+ Broadcaster(const sp& workDirectory);
+
+ void setHandler(const sp& handler);
+
+ /**
+ * Reset the beginning timestamp for broadcasts. Call this when
+ * the system_server restarts.
+ */
+ void reset();
+
+ /**
+ * Remove the history record for the broadcasts, including pending authorizations
+ * if necessary.
+ */
+ void clearBroadcasts(const string& pkg, const string& cls, const string& id);
+ void clearPackageBroadcasts(const string& pkg);
+
+ /**
+ * Send whichever broadcasts have been pending.
+ */
+ broadcast_status_t sendBroadcasts();
+
+private:
+ struct ReportId {
+ ReportId();
+ ReportId(const ReportId& that);
+ ReportId(const string& i, const string& p, const string& c);
+ ~ReportId();
+
+ bool operator<(const ReportId& that) const;
+
+ string id;
+ string pkg;
+ string cls;
+ };
+
+ class ConsentListener : public BnIncidentAuthListener {
+ public:
+ ConsentListener(const sp& broadcaster, const ReportId& reportId);
+ virtual ~ConsentListener();
+ virtual Status onReportApproved();
+ virtual Status onReportDenied();
+ private:
+ sp mBroadcaster;
+ ReportId mId;
+ };
+
+ struct ReportStatus {
+ ReportStatus();
+ ReportStatus(const ReportStatus& that);
+ ~ReportStatus();
+
+ bool approval_sent;
+ bool ready_sent;
+ sp listener;
+ };
+
+ sp mReportHandler;
+ sp mWorkDirectory;
+
+ // protected by mLock
+ mutex mLock;
+ map mHistory; // what we sent so we don't send it again
+ int64_t mLastSent;
+
+ void set_last_sent(int64_t timestamp);
+ int64_t get_last_sent();
+ void print_report_statuses() const;
+ status_t send_approval_broadcasts(const string& id, const string& pkg, const string& cls);
+ void report_approved(const ReportId& reportId);
+ void report_denied(const ReportId& reportId);
+ status_t send_report_ready_broadcasts(const string& id, const string& pkg, const string& cls);
+ status_t send_to_dropbox(const sp& file, const IncidentReportArgs& args);
+ bool was_approval_sent(const string& id, const string& pkg, const string& cls);
+ void set_approval_sent(const string& id, const string& pkg, const string& cls,
+ const sp& listener);
+ bool was_ready_sent(const string& id, const string& pkg, const string& cls);
+ void set_ready_sent(const string& id, const string& pkg, const string& cls);
+ sp get_incident_companion();
+};
+
+
+} // namespace incidentd
+} // namespace os
+} // namespace android
+
diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp
index 04819ec75a09db146917b078ba8c9d5f3597d586..b46c9e357fc4d408bfdce63e893447c3d390994c 100644
--- a/cmds/incidentd/src/FdBuffer.cpp
+++ b/cmds/incidentd/src/FdBuffer.cpp
@@ -31,12 +31,18 @@ namespace os {
namespace incidentd {
const ssize_t BUFFER_SIZE = 16 * 1024; // 16 KB
-const ssize_t MAX_BUFFER_COUNT = 256; // 4 MB max
+const ssize_t MAX_BUFFER_COUNT = 1536; // 24 MB max
FdBuffer::FdBuffer()
- : mBuffer(BUFFER_SIZE), mStartTime(-1), mFinishTime(-1), mTimedOut(false), mTruncated(false) {}
+ :mBuffer(new EncodedBuffer(BUFFER_SIZE)),
+ mStartTime(-1),
+ mFinishTime(-1),
+ mTimedOut(false),
+ mTruncated(false) {
+}
-FdBuffer::~FdBuffer() {}
+FdBuffer::~FdBuffer() {
+}
status_t FdBuffer::read(int fd, int64_t timeout) {
struct pollfd pfds = {.fd = fd, .events = POLLIN};
@@ -45,12 +51,12 @@ status_t FdBuffer::read(int fd, int64_t timeout) {
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
while (true) {
- if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
+ if (mBuffer->size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
mTruncated = true;
VLOG("Truncating data");
break;
}
- if (mBuffer.writeBuffer() == NULL) {
+ if (mBuffer->writeBuffer() == NULL) {
VLOG("No memory");
return NO_MEMORY;
}
@@ -76,7 +82,7 @@ status_t FdBuffer::read(int fd, int64_t timeout) {
return errno != 0 ? -errno : UNKNOWN_ERROR;
} else {
ssize_t amt = TEMP_FAILURE_RETRY(
- ::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite()));
+ ::read(fd, mBuffer->writeBuffer(), mBuffer->currentToWrite()));
if (amt < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
continue;
@@ -88,7 +94,7 @@ status_t FdBuffer::read(int fd, int64_t timeout) {
VLOG("Reached EOF of fd=%d", fd);
break;
}
- mBuffer.wp()->move(amt);
+ mBuffer->wp()->move(amt);
}
}
}
@@ -100,28 +106,28 @@ status_t FdBuffer::readFully(int fd) {
mStartTime = uptimeMillis();
while (true) {
- if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
+ if (mBuffer->size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
// Don't let it get too big.
mTruncated = true;
VLOG("Truncating data");
break;
}
- if (mBuffer.writeBuffer() == NULL) {
+ if (mBuffer->writeBuffer() == NULL) {
VLOG("No memory");
return NO_MEMORY;
}
ssize_t amt =
- TEMP_FAILURE_RETRY(::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite()));
+ TEMP_FAILURE_RETRY(::read(fd, mBuffer->writeBuffer(), mBuffer->currentToWrite()));
if (amt < 0) {
VLOG("Fail to read %d: %s", fd, strerror(errno));
return -errno;
} else if (amt == 0) {
- VLOG("Done reading %zu bytes", mBuffer.size());
+ VLOG("Done reading %zu bytes", mBuffer->size());
// We're done.
break;
}
- mBuffer.wp()->move(amt);
+ mBuffer->wp()->move(amt);
}
mFinishTime = uptimeMillis();
@@ -150,12 +156,12 @@ status_t FdBuffer::readProcessedDataInStream(int fd, unique_fd toFd, unique_fd f
// This is the buffer used to store processed data
while (true) {
- if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
+ if (mBuffer->size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
VLOG("Truncating data");
mTruncated = true;
break;
}
- if (mBuffer.writeBuffer() == NULL) {
+ if (mBuffer->writeBuffer() == NULL) {
VLOG("No memory");
return NO_MEMORY;
}
@@ -248,7 +254,7 @@ status_t FdBuffer::readProcessedDataInStream(int fd, unique_fd toFd, unique_fd f
// read from parsing process
ssize_t amt = TEMP_FAILURE_RETRY(
- ::read(fromFd.get(), mBuffer.writeBuffer(), mBuffer.currentToWrite()));
+ ::read(fromFd.get(), mBuffer->writeBuffer(), mBuffer->currentToWrite()));
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
VLOG("Fail to read fromFd %d: %s", fromFd.get(), strerror(errno));
@@ -258,7 +264,7 @@ status_t FdBuffer::readProcessedDataInStream(int fd, unique_fd toFd, unique_fd f
VLOG("Reached EOF of fromFd %d", fromFd.get());
break;
} else {
- mBuffer.wp()->move(amt);
+ mBuffer->wp()->move(amt);
}
}
@@ -266,9 +272,25 @@ status_t FdBuffer::readProcessedDataInStream(int fd, unique_fd toFd, unique_fd f
return NO_ERROR;
}
-size_t FdBuffer::size() const { return mBuffer.size(); }
+status_t FdBuffer::write(uint8_t const* buf, size_t size) {
+ return mBuffer->writeRaw(buf, size);
+}
+
+status_t FdBuffer::write(const sp& reader) {
+ return mBuffer->writeRaw(reader);
+}
+
+status_t FdBuffer::write(const sp& reader, size_t size) {
+ return mBuffer->writeRaw(reader, size);
+}
-EncodedBuffer::iterator FdBuffer::data() const { return mBuffer.begin(); }
+size_t FdBuffer::size() const {
+ return mBuffer->size();
+}
+
+sp FdBuffer::data() const {
+ return mBuffer;
+}
} // namespace incidentd
} // namespace os
diff --git a/cmds/incidentd/src/FdBuffer.h b/cmds/incidentd/src/FdBuffer.h
index 20deefd02558d3dd1c714485df95ff95dd6ca0a6..a3493604f425bb5d8b279b004b5f7b44e304f8d7 100644
--- a/cmds/incidentd/src/FdBuffer.h
+++ b/cmds/incidentd/src/FdBuffer.h
@@ -63,6 +63,21 @@ public:
status_t readProcessedDataInStream(int fd, unique_fd toFd, unique_fd fromFd, int64_t timeoutMs,
const bool isSysfs = false);
+ /**
+ * Write by hand into the buffer.
+ */
+ status_t write(uint8_t const* buf, size_t size);
+
+ /**
+ * Write all the data from a ProtoReader into our internal buffer.
+ */
+ status_t write(const sp& data);
+
+ /**
+ * Write size bytes of data from a ProtoReader into our internal buffer.
+ */
+ status_t write(const sp& data, size_t size);
+
/**
* Whether we timed out.
*/
@@ -89,17 +104,12 @@ public:
int64_t durationMs() const { return mFinishTime - mStartTime; }
/**
- * Reader API for data stored in FdBuffer
- */
- EncodedBuffer::iterator data() const;
-
- /**
- * Return the internal buffer, don't call unless you are familiar with EncodedBuffer.
+ * Get the EncodedBuffer inside.
*/
- EncodedBuffer* getInternalBuffer() { return &mBuffer; }
+ sp data() const;
private:
- EncodedBuffer mBuffer;
+ sp mBuffer;
int64_t mStartTime;
int64_t mFinishTime;
bool mTimedOut;
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index f8fb4a676ba0ddd4dccb07f1d285899e564046e8..4ba31b45e81cd693d334d7ec6c2a45486d86742a 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -19,7 +19,7 @@
#include "IncidentService.h"
#include "FdBuffer.h"
-#include "PrivacyBuffer.h"
+#include "PrivacyFilter.h"
#include "Reporter.h"
#include "incidentd_util.h"
#include "section_list.h"
@@ -35,9 +35,12 @@
#include
-enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
+enum {
+ WHAT_TAKE_REPORT = 1,
+ WHAT_SEND_BROADCASTS = 2
+};
-#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
+#define DEFAULT_DELAY_NS (1000000000LL)
#define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024) // 20MB
#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day
@@ -53,6 +56,7 @@ namespace android {
namespace os {
namespace incidentd {
+String16 const APPROVE_INCIDENT_REPORTS("android.permission.APPROVE_INCIDENT_REPORTS");
String16 const DUMP_PERMISSION("android.permission.DUMP");
String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
@@ -60,7 +64,14 @@ static Status checkIncidentPermissions(const IncidentReportArgs& args) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
pid_t callingPid = IPCThreadState::self()->getCallingPid();
if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
- // root doesn't have permission.DUMP if don't do this!
+ // Root and shell are ok.
+ return Status::ok();
+ }
+
+ if (checkCallingPermission(APPROVE_INCIDENT_REPORTS)) {
+ // Permission controller (this is a singleton permission that is always granted
+ // exactly for PermissionController) is allowed to access incident reports
+ // so it can show the user info about what they are approving.
return Status::ok();
}
@@ -81,8 +92,8 @@ static Status checkIncidentPermissions(const IncidentReportArgs& args) {
}
// checking calling request uid permission.
- switch (args.dest()) {
- case DEST_LOCAL:
+ switch (args.getPrivacyPolicy()) {
+ case PRIVACY_POLICY_LOCAL:
if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
callingPid, callingUid);
@@ -91,7 +102,7 @@ static Status checkIncidentPermissions(const IncidentReportArgs& args) {
"Calling process does not have permission to get local data.");
}
break;
- case DEST_EXPLICIT:
+ case PRIVACY_POLICY_EXPLICIT:
if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
callingUid != AID_SYSTEM) {
ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
@@ -105,78 +116,79 @@ static Status checkIncidentPermissions(const IncidentReportArgs& args) {
return Status::ok();
}
-// ================================================================================
-ReportRequestQueue::ReportRequestQueue() {}
-
-ReportRequestQueue::~ReportRequestQueue() {}
-
-void ReportRequestQueue::addRequest(const sp& request) {
- unique_lock lock(mLock);
- mQueue.push_back(request);
-}
-
-sp ReportRequestQueue::getNextRequest() {
- unique_lock lock(mLock);
- if (mQueue.empty()) {
- return NULL;
- } else {
- sp front(mQueue.front());
- mQueue.pop_front();
- return front;
- }
+static string build_uri(const string& pkg, const string& cls, const string& id) {
+ return "build_uri not implemented " + pkg + "/" + cls + "/" + id;
}
// ================================================================================
-ReportHandler::ReportHandler(const sp& handlerLooper, const sp& queue,
- const sp& throttler)
- : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
- mHandlerLooper(handlerLooper),
- mQueue(queue),
- mThrottler(throttler) {}
+ReportHandler::ReportHandler(const sp& workDirectory,
+ const sp& broadcaster, const sp& handlerLooper,
+ const sp& throttler)
+ :mLock(),
+ mWorkDirectory(workDirectory),
+ mBroadcaster(broadcaster),
+ mHandlerLooper(handlerLooper),
+ mBacklogDelay(DEFAULT_DELAY_NS),
+ mThrottler(throttler),
+ mBatch(new ReportBatch()) {
+}
-ReportHandler::~ReportHandler() {}
+ReportHandler::~ReportHandler() {
+}
void ReportHandler::handleMessage(const Message& message) {
switch (message.what) {
- case WHAT_RUN_REPORT:
- run_report();
+ case WHAT_TAKE_REPORT:
+ take_report();
break;
- case WHAT_SEND_BACKLOG_TO_DROPBOX:
- send_backlog_to_dropbox();
+ case WHAT_SEND_BROADCASTS:
+ send_broadcasts();
break;
}
}
-void ReportHandler::scheduleRunReport(const sp& request) {
- mQueue->addRequest(request);
- mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
- mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
+void ReportHandler::schedulePersistedReport(const IncidentReportArgs& args) {
+ mBatch->addPersistedReport(args);
+ mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
+ mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
+}
+
+void ReportHandler::scheduleStreamingReport(const IncidentReportArgs& args,
+ const sp& listener, int streamFd) {
+ mBatch->addStreamingReport(args, listener, streamFd);
+ mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
+ mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
}
-void ReportHandler::scheduleSendBacklogToDropbox() {
+void ReportHandler::scheduleSendBacklog() {
unique_lock lock(mLock);
- mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
- schedule_send_backlog_to_dropbox_locked();
+ mBacklogDelay = DEFAULT_DELAY_NS;
+ schedule_send_broadcasts_locked();
}
-void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
- mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
- mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
+void ReportHandler::schedule_send_broadcasts_locked() {
+ mHandlerLooper->removeMessages(this, WHAT_SEND_BROADCASTS);
+ mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BROADCASTS));
}
-void ReportHandler::run_report() {
- sp reporter = new Reporter();
+void ReportHandler::take_report() {
+ // Cycle the batch
+ sp batch;
+ {
+ unique_lock lock(mLock);
+ batch = mBatch;
+ mBatch = new ReportBatch();
+ }
- // Merge all of the requests into one that has all of the
- // requested fields.
- while (true) {
- sp request = mQueue->getNextRequest();
- if (request == NULL) {
- break;
- }
- reporter->batch.add(request);
+ if (batch->empty()) {
+ // Nothing to do.
+ return;
}
+ sp reporter = new Reporter(mWorkDirectory, batch);
+
+ // TODO: Do we really want to clear the reports if we throttle? Should we only throttle
+ // requests going to dropbox? How do we reconcile throttling with testing?
if (mThrottler->shouldThrottle()) {
ALOGW("RunReport got throttled.");
return;
@@ -185,46 +197,76 @@ void ReportHandler::run_report() {
// Take the report, which might take a while. More requests might queue
// up while we're doing this, and we'll handle them in their next batch.
// TODO: We should further rate-limit the reports to no more than N per time-period.
+ // TODO: Move this inside reporter.
size_t reportByteSize = 0;
- Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
+ reporter->runReport(&reportByteSize);
+
mThrottler->addReportSize(reportByteSize);
- if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
+
+ // Kick off the next steps, one of which is to send any new or otherwise remaining
+ // approvals, and one of which is to send any new or remaining broadcasts.
+ {
unique_lock lock(mLock);
- schedule_send_backlog_to_dropbox_locked();
+ schedule_send_broadcasts_locked();
}
}
-void ReportHandler::send_backlog_to_dropbox() {
- if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
+void ReportHandler::send_broadcasts() {
+ Broadcaster::broadcast_status_t result = mBroadcaster->sendBroadcasts();
+ if (result == Broadcaster::BROADCASTS_FINISHED) {
+ // We're done.
+ unique_lock lock(mLock);
+ mBacklogDelay = DEFAULT_DELAY_NS;
+ } else if (result == Broadcaster::BROADCASTS_REPEAT) {
+ // It worked, but there are more.
+ unique_lock lock(mLock);
+ mBacklogDelay = DEFAULT_DELAY_NS;
+ schedule_send_broadcasts_locked();
+ } else if (result == Broadcaster::BROADCASTS_BACKOFF) {
// There was a failure. Exponential backoff.
unique_lock lock(mLock);
mBacklogDelay *= 2;
ALOGI("Error sending to dropbox. Trying again in %lld minutes",
(mBacklogDelay / (1000000000LL * 60)));
- schedule_send_backlog_to_dropbox_locked();
- } else {
- mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
+ schedule_send_broadcasts_locked();
}
}
// ================================================================================
-IncidentService::IncidentService(const sp& handlerLooper)
- : mQueue(new ReportRequestQueue()),
- mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
- mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
+IncidentService::IncidentService(const sp& handlerLooper) {
+ mThrottler = new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS);
+ mWorkDirectory = new WorkDirectory();
+ mBroadcaster = new Broadcaster(mWorkDirectory);
+ mHandler = new ReportHandler(mWorkDirectory, mBroadcaster, handlerLooper,
+ mThrottler);
+ mBroadcaster->setHandler(mHandler);
}
IncidentService::~IncidentService() {}
Status IncidentService::reportIncident(const IncidentReportArgs& args) {
- ALOGI("reportIncident");
+ // TODO: Validate that the privacy policy is one of the real ones.
+ // If it isn't, clamp it to the next more restrictive real one.
+ // TODO: This function should reject the LOCAL privacy policy.
+ // Those have to stream.
+
+ // TODO: Check that the broadcast recevier has the proper permissions
+ // TODO: Maybe we should consider relaxing the permissions if it's going to
+ // dropbox, but definitely not if it's going to the broadcaster.
Status status = checkIncidentPermissions(args);
if (!status.isOk()) {
return status;
}
- mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
+ // If they didn't specify a component, use dropbox.
+ IncidentReportArgs argsCopy(args);
+ if (argsCopy.receiverPkg().length() == 0 && argsCopy.receiverCls().length() == 0) {
+ argsCopy.setReceiverPkg(DROPBOX_SENTINEL.getPackageName());
+ argsCopy.setReceiverCls(DROPBOX_SENTINEL.getClassName());
+ }
+
+ mHandler->schedulePersistedReport(argsCopy);
return Status::ok();
}
@@ -232,19 +274,29 @@ Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
const sp& listener,
const unique_fd& stream) {
- ALOGI("reportIncidentToStream");
+ // TODO: Validate that the privacy policy is one of the real ones.
+ // If it isn't, clamp it to the next more restrictive real one.
- Status status = checkIncidentPermissions(args);
+ // TODO: Only shell should be able to do a LOCAL privacy policy report.
+
+ // Streaming reports can not also be broadcast.
+ IncidentReportArgs argsCopy(args);
+ argsCopy.setReceiverPkg("");
+ argsCopy.setReceiverCls("");
+
+ Status status = checkIncidentPermissions(argsCopy);
if (!status.isOk()) {
return status;
}
+
+ // The ReportRequest takes ownership of the fd, so we need to dup it.
int fd = dup(stream.get());
if (fd < 0) {
return Status::fromStatusT(-errno);
}
- mHandler->scheduleRunReport(new ReportRequest(args, listener, fd));
+ mHandler->scheduleStreamingReport(argsCopy, listener, fd);
return Status::ok();
}
@@ -256,7 +308,92 @@ Status IncidentService::systemRunning() {
}
// When system_server is up and running, schedule the dropbox task to run.
- mHandler->scheduleSendBacklogToDropbox();
+ mBroadcaster->reset();
+ mHandler->scheduleSendBacklog();
+
+ return Status::ok();
+}
+
+Status IncidentService::getIncidentReportList(const String16& pkg16, const String16& cls16,
+ vector* result) {
+ status_t err;
+ const string pkg(String8(pkg16).string());
+ const string cls(String8(cls16).string());
+
+ // List the reports
+ vector> all;
+ err = mWorkDirectory->getReports(&all, 0);
+ if (err != NO_ERROR) {
+ return Status::fromStatusT(err);
+ }
+
+ // Find the ones that match pkg and cls.
+ for (sp& file: all) {
+ err = file->loadEnvelope();
+ if (err != NO_ERROR) {
+ continue;
+ }
+ const ReportFileProto& envelope = file->getEnvelope();
+ size_t reportCount = envelope.report_size();
+ for (int reportIndex = 0; reportIndex < reportCount; reportIndex++) {
+ const ReportFileProto_Report& report = envelope.report(reportIndex);
+ if (pkg == report.pkg() && cls == report.cls()) {
+ result->push_back(String16(build_uri(pkg, cls, file->getId()).c_str()));
+ break;
+ }
+ }
+ }
+
+ return Status::ok();
+}
+
+Status IncidentService::getIncidentReport(const String16& pkg16, const String16& cls16,
+ const String16& id16, IncidentManager::IncidentReport* result) {
+ status_t err;
+
+ const string pkg(String8(pkg16).string());
+ const string cls(String8(cls16).string());
+ const string id(String8(id16).string());
+
+ IncidentReportArgs args;
+ sp file = mWorkDirectory->getReport(pkg, cls, id, &args);
+ if (file != nullptr) {
+ int fd;
+ err = file->startFilteringData(&fd, args);
+ if (err != 0) {
+ ALOGW("Error reading data file that we think should exist: %s",
+ file->getDataFileName().c_str());
+ return Status::ok();
+ }
+
+ result->setTimestampNs(file->getTimestampNs());
+ result->setPrivacyPolicy(file->getEnvelope().privacy_policy());
+ result->takeFileDescriptor(fd);
+ }
+
+ return Status::ok();
+}
+
+Status IncidentService::deleteIncidentReports(const String16& pkg16, const String16& cls16,
+ const String16& id16) {
+ const string pkg(String8(pkg16).string());
+ const string cls(String8(cls16).string());
+ const string id(String8(id16).string());
+
+ sp file = mWorkDirectory->getReport(pkg, cls, id, nullptr);
+ if (file != nullptr) {
+ mWorkDirectory->commit(file, pkg, cls);
+ }
+ mBroadcaster->clearBroadcasts(pkg, cls, id);
+
+ return Status::ok();
+}
+
+Status IncidentService::deleteAllIncidentReports(const String16& pkg16) {
+ const string pkg(String8(pkg16).string());
+
+ mWorkDirectory->commitAll(pkg);
+ mBroadcaster->clearPackageBroadcasts(pkg);
return Status::ok();
}
@@ -354,7 +491,7 @@ status_t IncidentService::cmd_help(FILE* out) {
static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
if (p == NULL) return;
- fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
+ fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->policy);
if (p->children == NULL) return;
for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
printPrivacy(p->children[i], out, indent + " ");
@@ -362,6 +499,8 @@ static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
}
status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector& args) {
+ (void)in;
+
const int argCount = args.size();
if (argCount >= 3) {
String8 opt = args[1];
@@ -376,6 +515,7 @@ status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector 3 ? atoi(args[3]) : -1);
error = pBuf.strip(spec);
if (error != NO_ERROR) {
- fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
+ fprintf(err, "Error strip pii fields with spec %d\n", spec.policy);
return error;
}
return pBuf.flush(fileno(out));
+ */
+ return -1;
}
} else {
return cmd_help(out);
@@ -408,7 +550,7 @@ status_t IncidentService::dump(int fd, const Vector& args) {
ALOGD("Dump incident proto");
IncidentReportArgs incidentArgs;
- incidentArgs.setDest(DEST_EXPLICIT);
+ incidentArgs.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT);
int skipped[] = SKIPPED_SECTIONS;
for (const Section** section = SECTION_LIST; *section; section++) {
const int id = (*section)->id;
@@ -421,12 +563,16 @@ status_t IncidentService::dump(int fd, const Vector& args) {
return PERMISSION_DENIED;
}
+ // The ReportRequest takes ownership of the fd, so we need to dup it.
int fd1 = dup(fd);
if (fd1 < 0) {
return -errno;
}
- mHandler->scheduleRunReport(new ReportRequest(incidentArgs, NULL, fd1));
+ // TODO: Remove this. Someone even dumpstate, wanting to get an incident report
+ // should use the API. That will take making dumpstated call the API, which is a
+ // good thing. It also means it won't be subject to the timeout.
+ mHandler->scheduleStreamingReport(incidentArgs, NULL, fd1);
return NO_ERROR;
}
diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h
index c63a183b70b95b2523883beba941bb4a742345ee..6481321bbd69c204a67dcadb0389b24271a1ba84 100644
--- a/cmds/incidentd/src/IncidentService.h
+++ b/cmds/incidentd/src/IncidentService.h
@@ -20,13 +20,16 @@
#include "Reporter.h"
+#include "Broadcaster.h"
+#include "Throttler.h"
+#include "WorkDirectory.h"
+
#include
#include
-#include
+#include
#include
-#include "Throttler.h"
namespace android {
namespace os {
@@ -37,61 +40,75 @@ using namespace android::base;
using namespace android::binder;
using namespace android::os;
-// ================================================================================
-class ReportRequestQueue : public virtual RefBase {
-public:
- ReportRequestQueue();
- virtual ~ReportRequestQueue();
-
- void addRequest(const sp& request);
- sp getNextRequest();
-
-private:
- mutex mLock;
- deque > mQueue;
-};
-
// ================================================================================
class ReportHandler : public MessageHandler {
public:
- ReportHandler(const sp& handlerLooper, const sp& queue,
- const sp& throttler);
+ ReportHandler(const sp& workDirectory,
+ const sp& broadcaster, const sp& handlerLooper,
+ const sp& throttler);
virtual ~ReportHandler();
virtual void handleMessage(const Message& message);
/**
- * Adds a ReportRequest to the queue.
+ * Schedule a report for the "main" report, where it will be delivered to
+ * the uploaders and/or dropbox.
*/
- void scheduleRunReport(const sp& request);
+ void schedulePersistedReport(const IncidentReportArgs& args);
+
+ /**
+ * Adds a ReportRequest to the queue for one that has a listener an and fd
+ */
+ void scheduleStreamingReport(const IncidentReportArgs& args,
+ const sp& listener,
+ int streamFd);
/**
* Resets mBacklogDelay to the default and schedules sending
* the messages to dropbox.
*/
- void scheduleSendBacklogToDropbox();
+ void scheduleSendBacklog();
private:
mutex mLock;
- nsecs_t mBacklogDelay;
+
+ sp mWorkDirectory;
+ sp mBroadcaster;
+
sp mHandlerLooper;
- sp mQueue;
+ nsecs_t mBacklogDelay;
sp mThrottler;
+ sp mBatch;
+
/**
* Runs all of the reports that have been queued.
*/
- void run_report();
+ void take_report();
+
+ /**
+ * Schedules permission controller approve the reports.
+ */
+ void schedule_send_approvals_locked();
/**
- * Schedules a dropbox task mBacklogDelay nanoseconds from now.
+ * Sends the approvals to the PermissionController
*/
- void schedule_send_backlog_to_dropbox_locked();
+ void send_approvals();
/**
- * Sends the backlog to the dropbox service.
+ * Schedules the broadcasts that reports are complete mBacklogDelay nanoseconds from now.
+ * The delay is because typically when an incident report is taken, the system is not
+ * really in a happy state. So we wait a bit before sending the report to let things
+ * quiet down if they can. The urgency is in taking the report, not sharing the report.
+ * However, we don
*/
- void send_backlog_to_dropbox();
+ void schedule_send_broadcasts_locked();
+
+ /**
+ * Sends the broadcasts to the dropbox service.
+ */
+ void send_broadcasts();
};
// ================================================================================
@@ -108,6 +125,17 @@ public:
virtual Status systemRunning();
+ virtual Status getIncidentReportList(const String16& pkg, const String16& cls,
+ vector* result);
+
+ virtual Status getIncidentReport(const String16& pkg, const String16& cls,
+ const String16& id, IncidentManager::IncidentReport* result);
+
+ virtual Status deleteIncidentReports(const String16& pkg, const String16& cls,
+ const String16& id);
+
+ virtual Status deleteAllIncidentReports(const String16& pkg);
+
// Implement commands for debugging purpose.
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) override;
@@ -115,7 +143,8 @@ public:
virtual status_t dump(int fd, const Vector& args);
private:
- sp mQueue;
+ sp mWorkDirectory;
+ sp mBroadcaster;
sp mHandler;
sp mThrottler;
diff --git a/cmds/incidentd/src/Privacy.cpp b/cmds/incidentd/src/Privacy.cpp
index 6e55f906087cc4a730bfb2bb2ab8467b19f1dee6..386303b038e7a3f9f4e0b40bdfb6aa69f1baebae 100644
--- a/cmds/incidentd/src/Privacy.cpp
+++ b/cmds/incidentd/src/Privacy.cpp
@@ -23,6 +23,8 @@ namespace android {
namespace os {
namespace incidentd {
+using namespace android::os;
+
uint64_t encode_field_id(const Privacy* p) { return (uint64_t)p->type << 32 | p->field_id; }
const Privacy* lookup(const Privacy* p, uint32_t fieldId) {
@@ -35,39 +37,48 @@ const Privacy* lookup(const Privacy* p, uint32_t fieldId) {
return NULL;
}
-static bool allowDest(const uint8_t dest, const uint8_t policy) {
- switch (policy) {
- case android::os::DEST_LOCAL:
- return dest == android::os::DEST_LOCAL;
- case android::os::DEST_EXPLICIT:
- case DEST_UNSET:
- return dest == android::os::DEST_LOCAL || dest == android::os::DEST_EXPLICIT ||
- dest == DEST_UNSET;
- case android::os::DEST_AUTOMATIC:
+static bool isAllowed(const uint8_t policy, const uint8_t check) {
+ switch (check) {
+ case PRIVACY_POLICY_LOCAL:
+ return policy == PRIVACY_POLICY_LOCAL;
+ case PRIVACY_POLICY_EXPLICIT:
+ case PRIVACY_POLICY_UNSET:
+ return policy == PRIVACY_POLICY_LOCAL
+ || policy == PRIVACY_POLICY_EXPLICIT
+ || policy == PRIVACY_POLICY_UNSET;
+ case PRIVACY_POLICY_AUTOMATIC:
return true;
default:
return false;
}
}
-bool PrivacySpec::operator<(const PrivacySpec& other) const { return dest < other.dest; }
+PrivacySpec::PrivacySpec(uint8_t argPolicy) {
+ // TODO: Why on earth do we have two definitions of policy. Maybe
+ // it's not too late to clean this up.
+ switch (argPolicy) {
+ case android::os::PRIVACY_POLICY_AUTOMATIC:
+ case android::os::PRIVACY_POLICY_EXPLICIT:
+ case android::os::PRIVACY_POLICY_LOCAL:
+ mPolicy = argPolicy;
+ break;
+ default:
+ mPolicy = android::os::PRIVACY_POLICY_AUTOMATIC;
+ break;
+ }
+}
-bool PrivacySpec::CheckPremission(const Privacy* privacy, const uint8_t defaultDest) const {
- uint8_t policy = privacy != NULL ? privacy->dest : defaultDest;
- return allowDest(dest, policy);
+bool PrivacySpec::operator<(const PrivacySpec& that) const {
+ return mPolicy < that.mPolicy;
}
-bool PrivacySpec::RequireAll() const { return dest == android::os::DEST_LOCAL; }
+bool PrivacySpec::CheckPremission(const Privacy* privacy, const uint8_t defaultDest) const {
+ uint8_t check = privacy != NULL ? privacy->policy : defaultDest;
+ return isAllowed(mPolicy, check);
+}
-PrivacySpec PrivacySpec::new_spec(int dest) {
- switch (dest) {
- case android::os::DEST_AUTOMATIC:
- case android::os::DEST_EXPLICIT:
- case android::os::DEST_LOCAL:
- return PrivacySpec(dest);
- default:
- return PrivacySpec(android::os::DEST_AUTOMATIC);
- }
+bool PrivacySpec::RequireAll() const {
+ return mPolicy == android::os::PRIVACY_POLICY_LOCAL;
}
} // namespace incidentd
diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h
index a0159d9a8649fbca657f2d3d441123414087cc61..fc8caae7fc60a0f4801588af137a345a97e9f732 100644
--- a/cmds/incidentd/src/Privacy.h
+++ b/cmds/incidentd/src/Privacy.h
@@ -18,15 +18,15 @@
#ifndef PRIVACY_H
#define PRIVACY_H
+#include
+
#include
namespace android {
namespace os {
namespace incidentd {
-// This is the default value of DEST enum, sync with privacy.proto
-const uint8_t DEST_UNSET = 255; // DEST_UNSET is not exposed to libincident
-const uint8_t DEST_DEFAULT_VALUE = DEST_UNSET;
+using namespace android::os;
/*
* In order to NOT auto-generate large chuck of code by proto compiler in incidentd,
@@ -48,8 +48,8 @@ struct Privacy {
// This array is NULL-terminated.
Privacy** children;
- // DESTINATION Enum in frameworks/base/libs/incident/proto/android/privacy.proto.
- uint8_t dest;
+ // DESTINATION Enum in frameworks/base/core/proto/android/privacy.proto.
+ uint8_t policy;
// A list of regexp rules for stripping string fields in proto.
const char** patterns;
};
@@ -63,27 +63,28 @@ const Privacy* lookup(const Privacy* p, uint32_t fieldId);
/**
* PrivacySpec defines the request has what level of privacy authorization.
* For example, a device without user consent should only be able to upload AUTOMATIC fields.
- * DEST_UNSET are treated as DEST_EXPLICIT.
+ * PRIVACY_POLICY_UNSET are treated as PRIVACY_POLICY_EXPLICIT.
*/
class PrivacySpec {
public:
- const uint8_t dest;
+ explicit PrivacySpec(uint8_t argPolicy);
- PrivacySpec() : dest(DEST_DEFAULT_VALUE) {}
bool operator<(const PrivacySpec& other) const;
// check permission of a policy, if returns true, don't strip the data.
bool CheckPremission(const Privacy* privacy,
- const uint8_t defaultDest = DEST_DEFAULT_VALUE) const;
+ const uint8_t defaultPrivacyPolicy = PRIVACY_POLICY_UNSET) const;
// if returns true, no data need to be stripped.
bool RequireAll() const;
- // Constructs spec using static methods below.
- static PrivacySpec new_spec(int dest);
+ uint8_t getPolicy() const;
private:
- explicit PrivacySpec(uint8_t dest) : dest(dest) {}
+ // unimplemented constructors
+ explicit PrivacySpec();
+
+ uint8_t mPolicy;
};
} // namespace incidentd
diff --git a/cmds/incidentd/src/PrivacyBuffer.cpp b/cmds/incidentd/src/PrivacyBuffer.cpp
deleted file mode 100644
index 08f535db01facf67b9d65f30cc57a4becbe6a0da..0000000000000000000000000000000000000000
--- a/cmds/incidentd/src/PrivacyBuffer.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-#define DEBUG false
-#include "Log.h"
-
-#include "PrivacyBuffer.h"
-#include "incidentd_util.h"
-
-#include
-#include
-#include
-
-namespace android {
-namespace os {
-namespace incidentd {
-
-/**
- * Write the field to buf based on the wire type, iterator will point to next field.
- * If skip is set to true, no data will be written to buf. Return number of bytes written.
- */
-void PrivacyBuffer::writeFieldOrSkip(uint32_t fieldTag, bool skip) {
- uint8_t wireType = read_wire_type(fieldTag);
- size_t bytesToWrite = 0;
- uint64_t varint = 0;
-
- switch (wireType) {
- case WIRE_TYPE_VARINT:
- varint = mData.readRawVarint();
- if (!skip) {
- mProto.writeRawVarint(fieldTag);
- mProto.writeRawVarint(varint);
- }
- return;
- case WIRE_TYPE_FIXED64:
- if (!skip) mProto.writeRawVarint(fieldTag);
- bytesToWrite = 8;
- break;
- case WIRE_TYPE_LENGTH_DELIMITED:
- bytesToWrite = mData.readRawVarint();
- if (!skip) mProto.writeLengthDelimitedHeader(read_field_id(fieldTag), bytesToWrite);
- break;
- case WIRE_TYPE_FIXED32:
- if (!skip) mProto.writeRawVarint(fieldTag);
- bytesToWrite = 4;
- break;
- }
- if (skip) {
- mData.rp()->move(bytesToWrite);
- } else {
- for (size_t i = 0; i < bytesToWrite; i++) {
- mProto.writeRawByte(mData.next());
- }
- }
-}
-
-/**
- * Strip next field based on its private policy and request spec, then stores data in buf.
- * Return NO_ERROR if succeeds, otherwise BAD_VALUE is returned to indicate bad data in FdBuffer.
- *
- * The iterator must point to the head of a protobuf formatted field for successful operation.
- * After exit with NO_ERROR, iterator points to the next protobuf field's head.
- */
-status_t PrivacyBuffer::stripField(const Privacy* parentPolicy, const PrivacySpec& spec,
- int depth /* use as a counter for this recusive method. */) {
- if (!mData.hasNext() || parentPolicy == NULL) return BAD_VALUE;
- uint32_t fieldTag = mData.readRawVarint();
- uint32_t fieldId = read_field_id(fieldTag);
- const Privacy* policy = lookup(parentPolicy, fieldId);
-
- VLOG("[Depth %2d]Try to strip id %d, wiretype %d", depth, fieldId, read_wire_type(fieldTag));
- if (policy == NULL || policy->children == NULL) {
- bool skip = !spec.CheckPremission(policy, parentPolicy->dest);
- // iterator will point to head of next field
- size_t currentAt = mData.rp()->pos();
- writeFieldOrSkip(fieldTag, skip);
- VLOG("[Depth %2d]Field %d %ss %zu bytes", depth, fieldId, skip ? "skip" : "write",
- get_varint_size(fieldTag) + mData.rp()->pos() - currentAt);
- return NO_ERROR;
- }
- // current field is message type and its sub-fields have extra privacy policies
- uint32_t msgSize = mData.readRawVarint();
- size_t start = mData.rp()->pos();
- uint64_t token = mProto.start(encode_field_id(policy));
- while (mData.rp()->pos() - start != msgSize) {
- status_t err = stripField(policy, spec, depth + 1);
- if (err != NO_ERROR) {
- VLOG("Bad value when stripping id %d, wiretype %d, tag %#x, depth %d, size %d, "
- "relative pos %zu, ", fieldId, read_wire_type(fieldTag), fieldTag, depth,
- msgSize, mData.rp()->pos() - start);
- return err;
- }
- }
- mProto.end(token);
- return NO_ERROR;
-}
-
-// ================================================================================
-PrivacyBuffer::PrivacyBuffer(const Privacy* policy, EncodedBuffer::iterator data)
- : mPolicy(policy), mData(data), mProto(), mSize(0) {}
-
-PrivacyBuffer::~PrivacyBuffer() {}
-
-status_t PrivacyBuffer::strip(const PrivacySpec& spec) {
- VLOG("Strip with spec %d", spec.dest);
- // optimization when no strip happens
- if (mPolicy == NULL || mPolicy->children == NULL || spec.RequireAll()) {
- if (spec.CheckPremission(mPolicy)) mSize = mData.size();
- return NO_ERROR;
- }
- while (mData.hasNext()) {
- status_t err = stripField(mPolicy, spec, 0);
- if (err != NO_ERROR) return err; // Error logged in stripField.
- }
- if (mData.bytesRead() != mData.size()) {
- VLOG("Buffer corrupted: expect %zu bytes, read %zu bytes",
- mData.size(), mData.bytesRead());
- return BAD_VALUE;
- }
- mSize = mProto.size();
- mData.rp()->rewind(); // rewind the read pointer back to beginning after the strip.
- return NO_ERROR;
-}
-
-void PrivacyBuffer::clear() {
- mSize = 0;
- mProto.clear();
-}
-
-size_t PrivacyBuffer::size() const { return mSize; }
-
-status_t PrivacyBuffer::flush(int fd) {
- status_t err = NO_ERROR;
- EncodedBuffer::iterator iter = size() == mData.size() ? mData : mProto.data();
- while (iter.readBuffer() != NULL) {
- err = WriteFully(fd, iter.readBuffer(), iter.currentToRead()) ? NO_ERROR : -errno;
- iter.rp()->move(iter.currentToRead());
- if (err != NO_ERROR) return err;
- }
- return NO_ERROR;
-}
-
-} // namespace incidentd
-} // namespace os
-} // namespace android
diff --git a/cmds/incidentd/src/PrivacyBuffer.h b/cmds/incidentd/src/PrivacyBuffer.h
deleted file mode 100644
index eac3862b2cab0302648b92f2196bbb4621183810..0000000000000000000000000000000000000000
--- a/cmds/incidentd/src/PrivacyBuffer.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-#pragma once
-
-#ifndef PRIVACY_BUFFER_H
-#define PRIVACY_BUFFER_H
-
-#include "Privacy.h"
-
-#include
-#include
-#include
-#include
-
-namespace android {
-namespace os {
-namespace incidentd {
-
-using namespace android::util;
-
-/**
- * PrivacyBuffer holds the original protobuf data and strips PII-sensitive fields
- * based on the request and holds stripped data in its own buffer for output.
- */
-class PrivacyBuffer {
-public:
- PrivacyBuffer(const Privacy* policy, EncodedBuffer::iterator data);
- ~PrivacyBuffer();
-
- /**
- * Strip based on the request and hold data in its own buffer. Return NO_ERROR if strip
- * succeeds.
- */
- status_t strip(const PrivacySpec& spec);
-
- /**
- * Clear encoded buffer so it can be reused by another request.
- */
- void clear();
-
- /**
- * Return the size of the stripped data.
- */
- size_t size() const;
-
- /**
- * Flush buffer to the given fd. NO_ERROR is returned if the flush succeeds.
- */
- status_t flush(int fd);
-
-private:
- const Privacy* mPolicy;
- EncodedBuffer::iterator mData;
-
- ProtoOutputStream mProto;
- size_t mSize;
-
- status_t stripField(const Privacy* parentPolicy, const PrivacySpec& spec, int depth);
- void writeFieldOrSkip(uint32_t fieldTag, bool skip);
-};
-
-} // namespace incidentd
-} // namespace os
-} // namespace android
-
-#endif // PRIVACY_BUFFER_H
\ No newline at end of file
diff --git a/cmds/incidentd/src/PrivacyFilter.cpp b/cmds/incidentd/src/PrivacyFilter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7126322575d5cedf7d54efc08145e8c7b405cc79
--- /dev/null
+++ b/cmds/incidentd/src/PrivacyFilter.cpp
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+#define DEBUG false
+#include "Log.h"
+
+#include "incidentd_util.h"
+#include "PrivacyFilter.h"
+#include "proto_util.h"
+
+#include
+#include
+#include
+#include
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+// ================================================================================
+/**
+ * Write the field to buf based on the wire type, iterator will point to next field.
+ * If skip is set to true, no data will be written to buf. Return number of bytes written.
+ */
+void write_field_or_skip(ProtoOutputStream* out, const sp& in,
+ uint32_t fieldTag, bool skip) {
+ uint8_t wireType = read_wire_type(fieldTag);
+ size_t bytesToWrite = 0;
+ uint64_t varint = 0;
+
+ switch (wireType) {
+ case WIRE_TYPE_VARINT:
+ varint = in->readRawVarint();
+ if (!skip) {
+ out->writeRawVarint(fieldTag);
+ out->writeRawVarint(varint);
+ }
+ return;
+ case WIRE_TYPE_FIXED64:
+ if (!skip) {
+ out->writeRawVarint(fieldTag);
+ }
+ bytesToWrite = 8;
+ break;
+ case WIRE_TYPE_LENGTH_DELIMITED:
+ bytesToWrite = in->readRawVarint();
+ if (!skip) {
+ out->writeLengthDelimitedHeader(read_field_id(fieldTag), bytesToWrite);
+ }
+ break;
+ case WIRE_TYPE_FIXED32:
+ if (!skip) {
+ out->writeRawVarint(fieldTag);
+ }
+ bytesToWrite = 4;
+ break;
+ }
+ if (skip) {
+ in->move(bytesToWrite);
+ } else {
+ for (size_t i = 0; i < bytesToWrite; i++) {
+ out->writeRawByte(in->next());
+ }
+ }
+}
+
+/**
+ * Strip next field based on its private policy and request spec, then stores data in buf.
+ * Return NO_ERROR if succeeds, otherwise BAD_VALUE is returned to indicate bad data in
+ * FdBuffer.
+ *
+ * The iterator must point to the head of a protobuf formatted field for successful operation.
+ * After exit with NO_ERROR, iterator points to the next protobuf field's head.
+ *
+ * depth is the depth of recursion, for debugging.
+ */
+status_t strip_field(ProtoOutputStream* out, const sp& in,
+ const Privacy* parentPolicy, const PrivacySpec& spec, int depth) {
+ if (!in->hasNext() || parentPolicy == NULL) {
+ return BAD_VALUE;
+ }
+ uint32_t fieldTag = in->readRawVarint();
+ uint32_t fieldId = read_field_id(fieldTag);
+ const Privacy* policy = lookup(parentPolicy, fieldId);
+
+ if (policy == NULL || policy->children == NULL) {
+ bool skip = !spec.CheckPremission(policy, parentPolicy->policy);
+ // iterator will point to head of next field
+ size_t currentAt = in->bytesRead();
+ write_field_or_skip(out, in, fieldTag, skip);
+ return NO_ERROR;
+ }
+ // current field is message type and its sub-fields have extra privacy policies
+ uint32_t msgSize = in->readRawVarint();
+ size_t start = in->bytesRead();
+ uint64_t token = out->start(encode_field_id(policy));
+ while (in->bytesRead() - start != msgSize) {
+ status_t err = strip_field(out, in, policy, spec, depth + 1);
+ if (err != NO_ERROR) {
+ ALOGW("Bad value when stripping id %d, wiretype %d, tag %#x, depth %d, size %d, "
+ "relative pos %zu, ", fieldId, read_wire_type(fieldTag), fieldTag, depth,
+ msgSize, in->bytesRead() - start);
+ return err;
+ }
+ }
+ out->end(token);
+ return NO_ERROR;
+}
+
+// ================================================================================
+class FieldStripper {
+public:
+ FieldStripper(const Privacy* restrictions, const sp& data,
+ uint8_t bufferLevel);
+
+ /**
+ * Take the data that we have, and filter it down so that no fields
+ * are more sensitive than the given privacy policy.
+ */
+ status_t strip(uint8_t privacyPolicy);
+
+ /**
+ * At the current filter level, how many bytes of data there is.
+ */
+ ssize_t dataSize() const { return mSize; }
+
+ /**
+ * Write the data from the current filter level to the file descriptor.
+ */
+ status_t writeData(int fd);
+
+private:
+ /**
+ * The global set of field --> required privacy level mapping.
+ */
+ const Privacy* mRestrictions;
+
+ /**
+ * The current buffer.
+ */
+ sp mData;
+
+ /**
+ * The current size of the buffer inside mData.
+ */
+ ssize_t mSize;
+
+ /**
+ * The current privacy policy that the data is filtered to, as an optimization
+ * so we don't always re-filter data that has already been filtered.
+ */
+ uint8_t mCurrentLevel;
+
+};
+
+FieldStripper::FieldStripper(const Privacy* restrictions, const sp& data,
+ uint8_t bufferLevel)
+ :mRestrictions(restrictions),
+ mData(data),
+ mSize(data->size()),
+ mCurrentLevel(bufferLevel) {
+ if (mSize < 0) {
+ ALOGW("FieldStripper constructed with a ProtoReader that doesn't support size."
+ " Data will be missing.");
+ }
+}
+
+status_t FieldStripper::strip(const uint8_t privacyPolicy) {
+ // If the current strip level is less (fewer fields retained) than what's already in the
+ // buffer, then we can skip it.
+ if (mCurrentLevel < privacyPolicy) {
+ PrivacySpec spec(privacyPolicy);
+ ProtoOutputStream proto;
+
+ // Optimization when no strip happens.
+ if (mRestrictions == NULL || mRestrictions->children == NULL || spec.RequireAll()) {
+ if (spec.CheckPremission(mRestrictions)) {
+ mSize = mData->size();
+ }
+ return NO_ERROR;
+ }
+
+ while (mData->hasNext()) {
+ status_t err = strip_field(&proto, mData, mRestrictions, spec, 0);
+ if (err != NO_ERROR) {
+ return err; // Error logged in strip_field.
+ }
+ }
+
+ if (mData->bytesRead() != mData->size()) {
+ ALOGW("Buffer corrupted: expect %zu bytes, read %zu bytes", mData->size(),
+ mData->bytesRead());
+ return BAD_VALUE;
+ }
+
+ mData = proto.data();
+ mSize = proto.size();
+ mCurrentLevel = privacyPolicy;
+ }
+ return NO_ERROR;
+}
+
+status_t FieldStripper::writeData(int fd) {
+ status_t err = NO_ERROR;
+ sp reader = mData;
+ while (reader->readBuffer() != NULL) {
+ err = WriteFully(fd, reader->readBuffer(), reader->currentToRead()) ? NO_ERROR : -errno;
+ reader->move(reader->currentToRead());
+ if (err != NO_ERROR) return err;
+ }
+ return NO_ERROR;
+}
+
+
+// ================================================================================
+FilterFd::FilterFd(uint8_t privacyPolicy, int fd)
+ :mPrivacyPolicy(privacyPolicy),
+ mFd(fd) {
+}
+
+FilterFd::~FilterFd() {
+}
+
+// ================================================================================
+PrivacyFilter::PrivacyFilter(int sectionId, const Privacy* restrictions)
+ :mSectionId(sectionId),
+ mRestrictions(restrictions),
+ mOutputs() {
+}
+
+PrivacyFilter::~PrivacyFilter() {
+}
+
+void PrivacyFilter::addFd(const sp& output) {
+ mOutputs.push_back(output);
+}
+
+status_t PrivacyFilter::writeData(const FdBuffer& buffer, uint8_t bufferLevel,
+ size_t* maxSize) {
+ status_t err;
+
+ if (maxSize != NULL) {
+ *maxSize = 0;
+ }
+
+ // Order the writes by privacy filter, with increasing levels of filtration,k
+ // so we can do the filter once, and then write many times.
+ sort(mOutputs.begin(), mOutputs.end(),
+ [](const sp& a, const sp& b) -> bool {
+ return a->getPrivacyPolicy() < b->getPrivacyPolicy();
+ });
+
+ uint8_t privacyPolicy = PRIVACY_POLICY_LOCAL; // a.k.a. no filtering
+ FieldStripper fieldStripper(mRestrictions, buffer.data()->read(), bufferLevel);
+ for (const sp& output: mOutputs) {
+ // Do another level of filtering if necessary
+ if (privacyPolicy != output->getPrivacyPolicy()) {
+ privacyPolicy = output->getPrivacyPolicy();
+ err = fieldStripper.strip(privacyPolicy);
+ if (err != NO_ERROR) {
+ // We can't successfully strip this data. We will skip
+ // the rest of this section.
+ return err;
+ }
+ }
+
+ // Write the resultant buffer to the fd, along with the header.
+ ssize_t dataSize = fieldStripper.dataSize();
+ if (dataSize > 0) {
+ err = write_section_header(output->getFd(), mSectionId, dataSize);
+ if (err != NO_ERROR) {
+ output->onWriteError(err);
+ continue;
+ }
+
+ err = fieldStripper.writeData(output->getFd());
+ if (err != NO_ERROR) {
+ output->onWriteError(err);
+ continue;
+ }
+ }
+
+ if (maxSize != NULL) {
+ if (dataSize > *maxSize) {
+ *maxSize = dataSize;
+ }
+ }
+ }
+
+ return NO_ERROR;
+}
+
+// ================================================================================
+class ReadbackFilterFd : public FilterFd {
+public:
+ ReadbackFilterFd(uint8_t privacyPolicy, int fd);
+
+ virtual void onWriteError(status_t err);
+ status_t getError() { return mError; }
+
+private:
+ status_t mError;
+};
+
+ReadbackFilterFd::ReadbackFilterFd(uint8_t privacyPolicy, int fd)
+ :FilterFd(privacyPolicy, fd),
+ mError(NO_ERROR) {
+}
+
+void ReadbackFilterFd::onWriteError(status_t err) {
+ mError = err;
+}
+
+// ================================================================================
+status_t filter_and_write_report(int to, int from, uint8_t bufferLevel,
+ const IncidentReportArgs& args) {
+ status_t err;
+ sp reader = new ProtoFileReader(from);
+
+ while (reader->hasNext()) {
+ uint64_t fieldTag = reader->readRawVarint();
+ uint32_t fieldId = read_field_id(fieldTag);
+ uint8_t wireType = read_wire_type(fieldTag);
+ if (wireType == WIRE_TYPE_LENGTH_DELIMITED && args.containsSection(fieldId)) {
+ // We need this field, but we need to strip it to the level provided in args.
+ PrivacyFilter filter(fieldId, get_privacy_of_section(fieldId));
+ filter.addFd(new ReadbackFilterFd(args.getPrivacyPolicy(), to));
+
+ // Read this section from the reader into an FdBuffer
+ size_t sectionSize = reader->readRawVarint();
+ FdBuffer sectionData;
+ err = sectionData.write(reader, sectionSize);
+ if (err != NO_ERROR) {
+ ALOGW("filter_and_write_report FdBuffer.write failed (this shouldn't happen): %s",
+ strerror(-err));
+ return err;
+ }
+
+ // Do the filter and write.
+ err = filter.writeData(sectionData, bufferLevel, nullptr);
+ if (err != NO_ERROR) {
+ ALOGW("filter_and_write_report filter.writeData had an error: %s", strerror(-err));
+ return err;
+ }
+ } else {
+ // We don't need this field. Incident does not have any direct children
+ // other than sections. So just skip them.
+ write_field_or_skip(NULL, reader, fieldTag, true);
+ }
+ }
+
+ err = reader->getError();
+ if (err != NO_ERROR) {
+ ALOGW("filter_and_write_report reader had an error: %s", strerror(-err));
+ return err;
+ }
+
+ return NO_ERROR;
+}
+
+} // namespace incidentd
+} // namespace os
+} // namespace android
diff --git a/cmds/incidentd/src/PrivacyFilter.h b/cmds/incidentd/src/PrivacyFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..76b28498a0aca8fc881a70e2efb9b41ee7418f84
--- /dev/null
+++ b/cmds/incidentd/src/PrivacyFilter.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+#pragma once
+
+#ifndef PRIVACY_BUFFER_H
+#define PRIVACY_BUFFER_H
+
+#include "Privacy.h"
+
+#include "FdBuffer.h"
+
+#include
+#include
+#include
+#include
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using namespace android::util;
+
+/**
+ * Class to wrap a file descriptor, so callers of PrivacyFilter
+ * can associate additional data with each fd for their own
+ * purposes.
+ */
+class FilterFd : public RefBase {
+public:
+ FilterFd(uint8_t privacyPolicy, int fd);
+ virtual ~FilterFd();
+
+ uint8_t getPrivacyPolicy() const { return mPrivacyPolicy; }
+ int getFd() { return mFd;}
+
+ virtual void onWriteError(status_t err) = 0;
+
+private:
+ uint8_t mPrivacyPolicy;
+ int mFd;
+};
+
+/**
+ * PrivacyFilter holds the original protobuf data and strips PII-sensitive fields
+ * for several requests, streaming them to a set of corresponding file descriptors.
+ */
+class PrivacyFilter {
+public:
+ /**
+ * Constructor, with the field --> privacy restrictions mapping.
+ */
+ PrivacyFilter(int sectionId, const Privacy* restrictions);
+
+ ~PrivacyFilter();
+
+ /**
+ * Add a target file descriptor, and the privacy policy to which
+ * it should be filtered.
+ */
+ void addFd(const sp& output);
+
+ /**
+ * Write the data, filtered according to the privacy specs, to each of the
+ * file descriptors. Any non-NO_ERROR return codes are fatal to the whole
+ * report. Individual write errors to streams are reported via the callbacks
+ * on the FilterFds.
+ *
+ * If maxSize is not NULL, it will be set to the maximum size buffer that
+ * was written (i.e. after filtering).
+ *
+ * The buffer is assumed to have already been filtered to bufferLevel.
+ */
+ status_t writeData(const FdBuffer& buffer, uint8_t bufferLevel, size_t* maxSize);
+
+private:
+ int mSectionId;
+ const Privacy* mRestrictions;
+ vector> mOutputs;
+};
+
+status_t filter_and_write_report(int to, int from, uint8_t bufferLevel,
+ const IncidentReportArgs& args);
+
+} // namespace incidentd
+} // namespace os
+} // namespace android
+
+#endif // PRIVACY_BUFFER_H
diff --git a/cmds/incidentd/src/Reporter.cpp b/cmds/incidentd/src/Reporter.cpp
index 8f62da202606ebb9cdabc1f759460826a857113e..e773e74bbf15d06cee749d497ee1c79ae6aad9b2 100644
--- a/cmds/incidentd/src/Reporter.cpp
+++ b/cmds/incidentd/src/Reporter.cpp
@@ -18,12 +18,17 @@
#include "Reporter.h"
+#include "incidentd_util.h"
#include "Privacy.h"
+#include "PrivacyFilter.h"
+#include "proto_util.h"
#include "report_directory.h"
#include "section_list.h"
-#include
+#include
#include
+#include
+#include
#include
#include
@@ -33,308 +38,664 @@
#include