summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/incident_helper/src/TextParserBase.h2
-rw-r--r--cmds/incidentd/README.md4
-rw-r--r--cmds/incidentd/incidentd.rc2
-rw-r--r--cmds/incidentd/src/FdBuffer.cpp4
-rw-r--r--cmds/incidentd/src/IncidentService.cpp27
-rw-r--r--cmds/incidentd/src/Reporter.cpp2
-rw-r--r--cmds/incidentd/src/Section.cpp52
-rw-r--r--cmds/incidentd/src/io_util.cpp2
-rw-r--r--cmds/incidentd/src/report_directory.cpp26
-rw-r--r--core/java/android/os/IPermissionController.aidl1
-rw-r--r--core/java/android/os/Process.java6
-rw-r--r--core/java/android/text/style/BackgroundColorSpan.java54
-rw-r--r--core/java/android/text/style/ForegroundColorSpan.java49
-rw-r--r--core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java57
-rw-r--r--core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java26
-rw-r--r--core/java/android/util/apk/ApkSignatureVerifier.java49
-rw-r--r--core/java/android/util/apk/ApkSigningBlockUtils.java20
-rw-r--r--core/java/android/util/apk/ApkVerityBuilder.java6
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java10
-rw-r--r--core/java/com/android/internal/util/DumpUtils.java1
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--data/etc/platform.xml3
-rw-r--r--docs/html/reference/images/text/style/backgroundcolorspan.pngbin0 -> 16410 bytes
-rw-r--r--docs/html/reference/images/text/style/foregroundcolorspan.pngbin0 -> 18636 bytes
-rw-r--r--packages/Shell/AndroidManifest.xml1
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java10
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java35
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java5
28 files changed, 359 insertions, 101 deletions
diff --git a/cmds/incident_helper/src/TextParserBase.h b/cmds/incident_helper/src/TextParserBase.h
index c41612de4eb3..166796673e25 100644
--- a/cmds/incident_helper/src/TextParserBase.h
+++ b/cmds/incident_helper/src/TextParserBase.h
@@ -68,4 +68,4 @@ public:
virtual status_t Parse(const int in, const int out) const;
};
-#endif // TEXT_PARSER_BASE_H \ No newline at end of file
+#endif // TEXT_PARSER_BASE_H
diff --git a/cmds/incidentd/README.md b/cmds/incidentd/README.md
index ad0fa08c7326..71c6deb18aac 100644
--- a/cmds/incidentd/README.md
+++ b/cmds/incidentd/README.md
@@ -12,8 +12,8 @@ Run the test on a device manually
```
root$ mmm -j frameworks/base/cmds/incidentd && \
-adb push $OUT/data/nativetest/incidentd_test/* /data/nativetest/incidentd_test/ && \
-adb shell /data/nativetest/incidentd_test/incidentd_test 2>/dev/null
+adb push $OUT/data/nativetest/incidentd_test/* /data/nativetest/ && \
+adb shell /data/nativetest/incidentd_test 2>/dev/null
```
Run the test via AndroidTest.xml
diff --git a/cmds/incidentd/incidentd.rc b/cmds/incidentd/incidentd.rc
index 66667dca2982..1bd146850ea9 100644
--- a/cmds/incidentd/incidentd.rc
+++ b/cmds/incidentd/incidentd.rc
@@ -19,4 +19,4 @@ service incidentd /system/bin/incidentd
on post-fs-data
# Create directory for incidentd
- mkdir /data/misc/incidents 0770 root root
+ mkdir /data/misc/incidents 0770 incidentd incidentd
diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp
index 30dd339a629b..0fff4e6dc4a0 100644
--- a/cmds/incidentd/src/FdBuffer.cpp
+++ b/cmds/incidentd/src/FdBuffer.cpp
@@ -63,12 +63,14 @@ FdBuffer::read(int fd, int64_t timeout)
int64_t remainingTime = (mStartTime + timeout) - uptimeMillis();
if (remainingTime <= 0) {
+ if (DEBUG) ALOGD("timed out due to long read");
mTimedOut = true;
break;
}
int count = poll(&pfds, 1, remainingTime);
if (count == 0) {
+ if (DEBUG) ALOGD("timed out due to block calling poll");
mTimedOut = true;
break;
} else if (count < 0) {
@@ -129,6 +131,7 @@ FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeou
int64_t remainingTime = (mStartTime + timeoutMs) - uptimeMillis();
if (remainingTime <= 0) {
+ if (DEBUG) ALOGD("timed out due to long read");
mTimedOut = true;
break;
}
@@ -136,6 +139,7 @@ FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeou
// wait for any pfds to be ready to perform IO
int count = poll(pfds, 3, remainingTime);
if (count == 0) {
+ if (DEBUG) ALOGD("timed out due to block calling poll");
mTimedOut = true;
break;
} else if (count < 0) {
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index c4b54bbbc022..a97eb861578e 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -43,8 +43,9 @@ String16 const DUMP_PERMISSION("android.permission.DUMP");
String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
static Status
-checkIncidentPermissions()
+checkIncidentPermissions(const IncidentReportArgs& args)
{
+ // checking calling permission.
if (!checkCallingPermission(DUMP_PERMISSION)) {
ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
@@ -57,10 +58,24 @@ checkIncidentPermissions()
return Status::fromExceptionCode(Status::EX_SECURITY,
"Calling process does not have permission: android.permission.USAGE_STATS");
}
+
+ // checking calling request uid permission.
+ uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ switch (args.dest()) {
+ case DEST_LOCAL:
+ if (callingUid != AID_SHELL || callingUid != AID_ROOT) {
+ return Status::fromExceptionCode(Status::EX_SECURITY,
+ "Calling process does not have permission to get local data.");
+ }
+ case DEST_EXPLICIT:
+ if (callingUid != AID_SHELL || callingUid != AID_ROOT ||
+ callingUid != AID_STATSD || callingUid != AID_SYSTEM) {
+ return Status::fromExceptionCode(Status::EX_SECURITY,
+ "Calling process does not have permission to get explicit data.");
+ }
+ }
return Status::ok();
}
-
-
// ================================================================================
ReportRequestQueue::ReportRequestQueue()
{
@@ -71,7 +86,7 @@ ReportRequestQueue::~ReportRequestQueue()
}
void
-ReportRequestQueue::addRequest(const sp<ReportRequest>& request)
+ReportRequestQueue::addRequest(const sp<ReportRequest>& request)
{
unique_lock<mutex> lock(mLock);
mQueue.push_back(request);
@@ -196,7 +211,7 @@ IncidentService::reportIncident(const IncidentReportArgs& args)
{
ALOGI("reportIncident");
- Status status = checkIncidentPermissions();
+ Status status = checkIncidentPermissions(args);
if (!status.isOk()) {
return status;
}
@@ -212,7 +227,7 @@ IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
{
ALOGI("reportIncidentToStream");
- Status status = checkIncidentPermissions();
+ Status status = checkIncidentPermissions(args);
if (!status.isOk()) {
return status;
}
diff --git a/cmds/incidentd/src/Reporter.cpp b/cmds/incidentd/src/Reporter.cpp
index 34930aa57321..bd559d6980f1 100644
--- a/cmds/incidentd/src/Reporter.cpp
+++ b/cmds/incidentd/src/Reporter.cpp
@@ -251,7 +251,7 @@ Reporter::create_file(int* fd)
// Override umask. Not super critical. If it fails go on with life.
chmod(filename, 0660);
- if (chown(filename, AID_SYSTEM, AID_SYSTEM)) {
+ if (chown(filename, AID_INCIDENTD, AID_INCIDENTD)) {
ALOGE("Unable to change ownership of incident file %s: %s\n", filename, strerror(errno));
status_t err = -errno;
unlink(mFilename.c_str());
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 61d16f815e65..0827785811b6 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -19,6 +19,7 @@
#include "Section.h"
#include <errno.h>
+#include <sys/prctl.h>
#include <unistd.h>
#include <wait.h>
@@ -30,7 +31,6 @@
#include <log/log_event_list.h>
#include <log/logprint.h>
#include <log/log_read.h>
-#include <private/android_filesystem_config.h> // for AID_NOBODY
#include <private/android_logger.h>
#include "FdBuffer.h"
@@ -55,26 +55,20 @@ static pid_t
fork_execute_incident_helper(const int id, const char* name, Fpipe& p2cPipe, Fpipe& c2pPipe)
{
const char* ihArgs[] { INCIDENT_HELPER, "-s", String8::format("%d", id).string(), NULL };
-
// fork used in multithreaded environment, avoid adding unnecessary code in child process
pid_t pid = fork();
if (pid == 0) {
- // child process executes incident helper as nobody
- if (setgid(AID_NOBODY) == -1) {
- ALOGW("%s can't change gid: %s", name, strerror(errno));
- _exit(EXIT_FAILURE);
- }
- if (setuid(AID_NOBODY) == -1) {
- ALOGW("%s can't change uid: %s", name, strerror(errno));
- _exit(EXIT_FAILURE);
- }
-
- if (dup2(p2cPipe.readFd(), STDIN_FILENO) != 0 || !p2cPipe.close() ||
- dup2(c2pPipe.writeFd(), STDOUT_FILENO) != 1 || !c2pPipe.close()) {
+ if (TEMP_FAILURE_RETRY(dup2(p2cPipe.readFd(), STDIN_FILENO)) != 0
+ || !p2cPipe.close()
+ || TEMP_FAILURE_RETRY(dup2(c2pPipe.writeFd(), STDOUT_FILENO)) != 1
+ || !c2pPipe.close()) {
ALOGW("%s can't setup stdin and stdout for incident helper", name);
_exit(EXIT_FAILURE);
}
+ /* make sure the child dies when incidentd dies */
+ prctl(PR_SET_PDEATHSIG, SIGKILL);
+
execv(INCIDENT_HELPER, const_cast<char**>(ihArgs));
ALOGW("%s failed in incident helper process: %s", name, strerror(errno));
@@ -87,11 +81,23 @@ fork_execute_incident_helper(const int id, const char* name, Fpipe& p2cPipe, Fpi
}
// ================================================================================
+static status_t statusCode(int status) {
+ if (WIFSIGNALED(status)) {
+ ALOGD("return by signal: %s", strerror(WTERMSIG(status)));
+ return -WTERMSIG(status);
+ } else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
+ ALOGD("return by exit: %s", strerror(WEXITSTATUS(status)));
+ return -WEXITSTATUS(status);
+ }
+ return NO_ERROR;
+}
+
static status_t kill_child(pid_t pid) {
int status;
+ ALOGD("try to kill child process %d", pid);
kill(pid, SIGKILL);
if (waitpid(pid, &status, 0) == -1) return -1;
- return WIFEXITED(status) == 0 ? NO_ERROR : -WEXITSTATUS(status);
+ return statusCode(status);
}
static status_t wait_child(pid_t pid) {
@@ -104,7 +110,7 @@ static status_t wait_child(pid_t pid) {
nanosleep(&WAIT_INTERVAL_NS, NULL);
}
if (!died) return kill_child(pid);
- return WIFEXITED(status) == 0 ? NO_ERROR : -WEXITSTATUS(status);
+ return statusCode(status);
}
// ================================================================================
static const Privacy*
@@ -275,9 +281,9 @@ FileSection::Execute(ReportRequestSet* requests) const
status_t readStatus = buffer.readProcessedDataInStream(fd, p2cPipe.writeFd(), c2pPipe.readFd(),
this->timeoutMs, mIsSysfs);
if (readStatus != NO_ERROR || buffer.timedOut()) {
- ALOGW("FileSection '%s' failed to read data from incident helper: %s, timedout: %s, kill: %s",
- this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false",
- strerror(-kill_child(pid)));
+ ALOGW("FileSection '%s' failed to read data from incident helper: %s, timedout: %s",
+ this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
+ kill_child(pid);
return readStatus;
}
@@ -543,10 +549,10 @@ CommandSection::Execute(ReportRequestSet* requests) const
close(cmdPipe.writeFd());
status_t readStatus = buffer.read(ihPipe.readFd(), this->timeoutMs);
if (readStatus != NO_ERROR || buffer.timedOut()) {
- ALOGW("CommandSection '%s' failed to read data from incident helper: %s, "
- "timedout: %s, kill command: %s, kill incident helper: %s",
- this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false",
- strerror(-kill_child(cmdPid)), strerror(-kill_child(ihPid)));
+ ALOGW("CommandSection '%s' failed to read data from incident helper: %s, timedout: %s",
+ this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
+ kill_child(cmdPid);
+ kill_child(ihPid);
return readStatus;
}
diff --git a/cmds/incidentd/src/io_util.cpp b/cmds/incidentd/src/io_util.cpp
index af4a35cc0015..90f543e30ff7 100644
--- a/cmds/incidentd/src/io_util.cpp
+++ b/cmds/incidentd/src/io_util.cpp
@@ -23,7 +23,7 @@
status_t write_all(int fd, uint8_t const* buf, size_t size)
{
while (size > 0) {
- ssize_t amt = ::write(fd, buf, size);
+ ssize_t amt = TEMP_FAILURE_RETRY(::write(fd, buf, size));
if (amt < 0) {
return -errno;
}
diff --git a/cmds/incidentd/src/report_directory.cpp b/cmds/incidentd/src/report_directory.cpp
index 65030b3a1799..20111d8ae89a 100644
--- a/cmds/incidentd/src/report_directory.cpp
+++ b/cmds/incidentd/src/report_directory.cpp
@@ -58,26 +58,9 @@ create_directory(const char* directory)
goto done;
}
} else {
- if (mkdir(dir, 0770)) {
- ALOGE("No incident reports today. "
- "Unable to create incident report dir %s: %s", dir,
- strerror(errno));
- err = -errno;
- goto done;
- }
- if (chmod(dir, 0770)) {
- ALOGE("No incident reports today. "
- "Unable to set permissions for incident report dir %s: %s", dir,
- strerror(errno));
- err = -errno;
- goto done;
- }
- if (chown(dir, AID_SYSTEM, AID_SYSTEM)) {
- ALOGE("No incident reports today. Unable to change ownership of dir %s: %s\n",
- dir, strerror(errno));
- err = -errno;
- goto done;
- }
+ ALOGE("No such directory %s, something wrong.", dir);
+ err = -1;
+ goto done;
}
if (!last) {
*d++ = '/';
@@ -97,8 +80,7 @@ create_directory(const char* directory)
err = BAD_VALUE;
goto done;
}
- if ((st.st_uid != AID_SYSTEM && st.st_uid != AID_ROOT) ||
- (st.st_gid != AID_SYSTEM && st.st_gid != AID_ROOT)) {
+ if (st.st_uid != AID_INCIDENTD || st.st_gid != AID_INCIDENTD) {
ALOGE("No incident reports today. Owner is %d and group is %d on report directory %s",
st.st_uid, st.st_gid, directory);
err = BAD_VALUE;
diff --git a/core/java/android/os/IPermissionController.aidl b/core/java/android/os/IPermissionController.aidl
index 5e8590af11f1..3de953a2dfbe 100644
--- a/core/java/android/os/IPermissionController.aidl
+++ b/core/java/android/os/IPermissionController.aidl
@@ -22,4 +22,5 @@ interface IPermissionController {
boolean checkPermission(String permission, int pid, int uid);
String[] getPackagesForUid(int uid);
boolean isRuntimePermission(String permission);
+ int getPackageUid(String packageName, int flags);
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index e6cf5e6a6cbf..7654e9b6ee22 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -151,6 +151,12 @@ public class Process {
*/
public static final int OTA_UPDATE_UID = 1061;
+ /**
+ * Defines the UID used for incidentd.
+ * @hide
+ */
+ public static final int INCIDENTD_UID = 1067;
+
/** {@hide} */
public static final int NOBODY_UID = 9999;
diff --git a/core/java/android/text/style/BackgroundColorSpan.java b/core/java/android/text/style/BackgroundColorSpan.java
index de05f50c9860..4f471a8a2f85 100644
--- a/core/java/android/text/style/BackgroundColorSpan.java
+++ b/core/java/android/text/style/BackgroundColorSpan.java
@@ -16,24 +16,48 @@
package android.text.style;
+import android.annotation.ColorInt;
+import android.annotation.NonNull;
import android.os.Parcel;
import android.text.ParcelableSpan;
import android.text.TextPaint;
import android.text.TextUtils;
+/**
+ * Changes the background color of the text to which the span is attached.
+ * <p>
+ * For example, to set a green background color for a text you would create a {@link
+ * android.text.SpannableStringBuilder} based on the text and set the span.
+ * <pre>{@code
+ * SpannableString string = new SpannableString("Text with a background color span");
+ *string.setSpan(new BackgroundColorSpan(color), 12, 28, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * }</pre>
+ * <img src="{@docRoot}reference/android/images/text/style/backgroundcolorspan.png" />
+ * <figcaption>Set a background color for the text.</figcaption>
+ */
public class BackgroundColorSpan extends CharacterStyle
implements UpdateAppearance, ParcelableSpan {
private final int mColor;
- public BackgroundColorSpan(int color) {
+ /**
+ * Creates a {@link BackgroundColorSpan} from a color integer.
+ * <p>
+ *
+ * @param color color integer that defines the background color
+ * @see android.content.res.Resources#getColor(int, Resources.Theme)
+ */
+ public BackgroundColorSpan(@ColorInt int color) {
mColor = color;
}
- public BackgroundColorSpan(Parcel src) {
+ /**
+ * Creates a {@link BackgroundColorSpan} from a parcel.
+ */
+ public BackgroundColorSpan(@NonNull Parcel src) {
mColor = src.readInt();
}
-
+
public int getSpanTypeId() {
return getSpanTypeIdInternal();
}
@@ -42,26 +66,40 @@ public class BackgroundColorSpan extends CharacterStyle
public int getSpanTypeIdInternal() {
return TextUtils.BACKGROUND_COLOR_SPAN;
}
-
+
public int describeContents() {
return 0;
}
- public void writeToParcel(Parcel dest, int flags) {
+ /**
+ * Flatten this object into a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ */
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
writeToParcelInternal(dest, flags);
}
/** @hide */
- public void writeToParcelInternal(Parcel dest, int flags) {
+ public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
dest.writeInt(mColor);
}
+ /**
+ * @return the background color of this span.
+ * @see BackgroundColorSpan#BackgroundColorSpan(int)
+ */
+ @ColorInt
public int getBackgroundColor() {
return mColor;
}
+ /**
+ * Updates the background color of the TextPaint.
+ */
@Override
- public void updateDrawState(TextPaint ds) {
- ds.bgColor = mColor;
+ public void updateDrawState(@NonNull TextPaint textPaint) {
+ textPaint.bgColor = mColor;
}
}
diff --git a/core/java/android/text/style/ForegroundColorSpan.java b/core/java/android/text/style/ForegroundColorSpan.java
index 2bc6d5406ade..08ab2a1f1a20 100644
--- a/core/java/android/text/style/ForegroundColorSpan.java
+++ b/core/java/android/text/style/ForegroundColorSpan.java
@@ -17,24 +17,48 @@
package android.text.style;
import android.annotation.ColorInt;
+import android.annotation.NonNull;
import android.os.Parcel;
import android.text.ParcelableSpan;
import android.text.TextPaint;
import android.text.TextUtils;
+/**
+ * Changes the color of the text to which the span is attached.
+ * <p>
+ * For example, to set a green text color you would create a {@link
+ * android.text.SpannableStringBuilder} based on the text and set the span.
+ * <pre>{@code
+ * SpannableString string = new SpannableString("Text with a foreground color span");
+ *string.setSpan(new ForegroundColorSpan(color), 12, 28, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * }</pre>
+ * <img src="{@docRoot}reference/android/images/text/style/foregroundcolorspan.png" />
+ * <figcaption>Set a text color.</figcaption>
+ */
public class ForegroundColorSpan extends CharacterStyle
implements UpdateAppearance, ParcelableSpan {
private final int mColor;
+ /**
+ * Creates a {@link ForegroundColorSpan} from a color integer.
+ * <p>
+ * To get the color integer associated with a particular color resource ID, use
+ * {@link android.content.res.Resources#getColor(int, Resources.Theme)}
+ *
+ * @param color color integer that defines the text color
+ */
public ForegroundColorSpan(@ColorInt int color) {
mColor = color;
}
- public ForegroundColorSpan(Parcel src) {
+ /**
+ * Creates a {@link ForegroundColorSpan} from a parcel.
+ */
+ public ForegroundColorSpan(@NonNull Parcel src) {
mColor = src.readInt();
}
-
+
public int getSpanTypeId() {
return getSpanTypeIdInternal();
}
@@ -48,22 +72,35 @@ public class ForegroundColorSpan extends CharacterStyle
return 0;
}
- public void writeToParcel(Parcel dest, int flags) {
+ /**
+ * Flatten this object into a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ */
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
writeToParcelInternal(dest, flags);
}
/** @hide */
- public void writeToParcelInternal(Parcel dest, int flags) {
+ public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
dest.writeInt(mColor);
}
+ /**
+ * @return the foreground color of this span.
+ * @see ForegroundColorSpan#ForegroundColorSpan(int)
+ */
@ColorInt
public int getForegroundColor() {
return mColor;
}
+ /**
+ * Updates the color of the TextPaint to the foreground color.
+ */
@Override
- public void updateDrawState(TextPaint ds) {
- ds.setColor(mColor);
+ public void updateDrawState(@NonNull TextPaint textPaint) {
+ textPaint.setColor(mColor);
}
}
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
index ce8998fcb863..5a09dab552e3 100644
--- a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
+++ b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
@@ -16,6 +16,7 @@
package android.util.apk;
+import static android.util.apk.ApkSigningBlockUtils.CONTENT_DIGEST_VERITY_CHUNKED_SHA256;
import static android.util.apk.ApkSigningBlockUtils.SIGNATURE_DSA_WITH_SHA256;
import static android.util.apk.ApkSigningBlockUtils.SIGNATURE_ECDSA_WITH_SHA256;
import static android.util.apk.ApkSigningBlockUtils.SIGNATURE_ECDSA_WITH_SHA512;
@@ -42,6 +43,7 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
+import java.security.DigestException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
@@ -105,7 +107,8 @@ public class ApkSignatureSchemeV2Verifier {
*/
public static X509Certificate[][] verify(String apkFile)
throws SignatureNotFoundException, SecurityException, IOException {
- return verify(apkFile, true);
+ VerifiedSigner vSigner = verify(apkFile, true);
+ return vSigner.certs;
}
/**
@@ -119,10 +122,11 @@ public class ApkSignatureSchemeV2Verifier {
*/
public static X509Certificate[][] plsCertsNoVerifyOnlyCerts(String apkFile)
throws SignatureNotFoundException, SecurityException, IOException {
- return verify(apkFile, false);
+ VerifiedSigner vSigner = verify(apkFile, false);
+ return vSigner.certs;
}
- private static X509Certificate[][] verify(String apkFile, boolean verifyIntegrity)
+ private static VerifiedSigner verify(String apkFile, boolean verifyIntegrity)
throws SignatureNotFoundException, SecurityException, IOException {
try (RandomAccessFile apk = new RandomAccessFile(apkFile, "r")) {
return verify(apk, verifyIntegrity);
@@ -138,7 +142,7 @@ public class ApkSignatureSchemeV2Verifier {
* verify.
* @throws IOException if an I/O error occurs while reading the APK file.
*/
- private static X509Certificate[][] verify(RandomAccessFile apk, boolean verifyIntegrity)
+ private static VerifiedSigner verify(RandomAccessFile apk, boolean verifyIntegrity)
throws SignatureNotFoundException, SecurityException, IOException {
SignatureInfo signatureInfo = findSignature(apk);
return verify(apk, signatureInfo, verifyIntegrity);
@@ -163,7 +167,7 @@ public class ApkSignatureSchemeV2Verifier {
* @param signatureInfo APK Signature Scheme v2 Block and information relevant for verifying it
* against the APK file.
*/
- private static X509Certificate[][] verify(
+ private static VerifiedSigner verify(
RandomAccessFile apk,
SignatureInfo signatureInfo,
boolean doVerifyIntegrity) throws SecurityException, IOException {
@@ -207,7 +211,14 @@ public class ApkSignatureSchemeV2Verifier {
ApkSigningBlockUtils.verifyIntegrity(contentDigests, apk, signatureInfo);
}
- return signerCerts.toArray(new X509Certificate[signerCerts.size()][]);
+ byte[] verityRootHash = null;
+ if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) {
+ verityRootHash = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256);
+ }
+
+ return new VerifiedSigner(
+ signerCerts.toArray(new X509Certificate[signerCerts.size()][]),
+ verityRootHash);
}
private static X509Certificate[] verifySigner(
@@ -383,6 +394,24 @@ public class ApkSignatureSchemeV2Verifier {
return;
}
+ static byte[] getVerityRootHash(String apkPath)
+ throws IOException, SignatureNotFoundException, SecurityException {
+ try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
+ SignatureInfo signatureInfo = findSignature(apk);
+ VerifiedSigner vSigner = verify(apk, false);
+ return vSigner.verityRootHash;
+ }
+ }
+
+ static byte[] generateApkVerity(String apkPath, ByteBufferFactory bufferFactory)
+ throws IOException, SignatureNotFoundException, SecurityException, DigestException,
+ NoSuchAlgorithmException {
+ try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
+ SignatureInfo signatureInfo = findSignature(apk);
+ return ApkSigningBlockUtils.generateApkVerity(apkPath, bufferFactory, signatureInfo);
+ }
+ }
+
private static boolean isSupportedSignatureAlgorithm(int sigAlgorithm) {
switch (sigAlgorithm) {
case SIGNATURE_RSA_PSS_WITH_SHA256:
@@ -400,4 +429,20 @@ public class ApkSignatureSchemeV2Verifier {
return false;
}
}
+
+ /**
+ * Verified APK Signature Scheme v2 signer.
+ *
+ * @hide for internal use only.
+ */
+ public static class VerifiedSigner {
+ public final X509Certificate[][] certs;
+ public final byte[] verityRootHash;
+
+ public VerifiedSigner(X509Certificate[][] certs, byte[] verityRootHash) {
+ this.certs = certs;
+ this.verityRootHash = verityRootHash;
+ }
+
+ }
}
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
index c9e67fe1c9ef..1b04eb2f7d44 100644
--- a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
+++ b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
@@ -16,6 +16,7 @@
package android.util.apk;
+import static android.util.apk.ApkSigningBlockUtils.CONTENT_DIGEST_VERITY_CHUNKED_SHA256;
import static android.util.apk.ApkSigningBlockUtils.SIGNATURE_DSA_WITH_SHA256;
import static android.util.apk.ApkSigningBlockUtils.SIGNATURE_ECDSA_WITH_SHA256;
import static android.util.apk.ApkSigningBlockUtils.SIGNATURE_ECDSA_WITH_SHA512;
@@ -43,6 +44,7 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
+import java.security.DigestException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
@@ -211,6 +213,10 @@ public class ApkSignatureSchemeV3Verifier {
ApkSigningBlockUtils.verifyIntegrity(contentDigests, apk, signatureInfo);
}
+ if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) {
+ result.verityRootHash = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256);
+ }
+
return result;
}
@@ -499,6 +505,24 @@ public class ApkSignatureSchemeV3Verifier {
return new VerifiedProofOfRotation(certs, flagsList);
}
+ static byte[] getVerityRootHash(String apkPath)
+ throws IOException, SignatureNotFoundException, SecurityException {
+ try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
+ SignatureInfo signatureInfo = findSignature(apk);
+ VerifiedSigner vSigner = verify(apk, false);
+ return vSigner.verityRootHash;
+ }
+ }
+
+ static byte[] generateApkVerity(String apkPath, ByteBufferFactory bufferFactory)
+ throws IOException, SignatureNotFoundException, SecurityException, DigestException,
+ NoSuchAlgorithmException {
+ try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
+ SignatureInfo signatureInfo = findSignature(apk);
+ return ApkSigningBlockUtils.generateApkVerity(apkPath, bufferFactory, signatureInfo);
+ }
+ }
+
private static boolean isSupportedSignatureAlgorithm(int sigAlgorithm) {
switch (sigAlgorithm) {
case SIGNATURE_RSA_PSS_WITH_SHA256:
@@ -541,6 +565,8 @@ public class ApkSignatureSchemeV3Verifier {
public final X509Certificate[] certs;
public final VerifiedProofOfRotation por;
+ public byte[] verityRootHash;
+
public VerifiedSigner(X509Certificate[] certs, VerifiedProofOfRotation por) {
this.certs = certs;
this.por = por;
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index 555c4740389a..a2a76169c83a 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -36,7 +36,9 @@ import libcore.io.IoUtils;
import java.io.IOException;
import java.io.InputStream;
+import java.security.DigestException;
import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.util.ArrayList;
@@ -367,4 +369,51 @@ public class ApkSignatureVerifier {
// v2 didn't work, try jarsigner
return verifyV1Signature(apkPath, false);
}
+
+ /**
+ * @return the verity root hash in the Signing Block.
+ */
+ public static byte[] getVerityRootHash(String apkPath)
+ throws IOException, SignatureNotFoundException, SecurityException {
+ // first try v3
+ try {
+ return ApkSignatureSchemeV3Verifier.getVerityRootHash(apkPath);
+ } catch (SignatureNotFoundException e) {
+ // try older version
+ }
+ return ApkSignatureSchemeV2Verifier.getVerityRootHash(apkPath);
+ }
+
+ /**
+ * Generates the Merkle tree and verity metadata to the buffer allocated by the {@code
+ * ByteBufferFactory}.
+ *
+ * @return the verity root hash of the generated Merkle tree.
+ */
+ public static byte[] generateApkVerity(String apkPath, ByteBufferFactory bufferFactory)
+ throws IOException, SignatureNotFoundException, SecurityException, DigestException,
+ NoSuchAlgorithmException {
+ // first try v3
+ try {
+ return ApkSignatureSchemeV3Verifier.generateApkVerity(apkPath, bufferFactory);
+ } catch (SignatureNotFoundException e) {
+ // try older version
+ }
+ return ApkSignatureSchemeV2Verifier.generateApkVerity(apkPath, bufferFactory);
+ }
+
+ /**
+ * Result of a successful APK verification operation.
+ */
+ public static class Result {
+ public final Certificate[][] certs;
+ public final Signature[] sigs;
+ public final int signatureSchemeVersion;
+
+ public Result(Certificate[][] certs, Signature[] sigs, int signingVersion) {
+ this.certs = certs;
+ this.sigs = sigs;
+ this.signatureSchemeVersion = signingVersion;
+ }
+ }
}
diff --git a/core/java/android/util/apk/ApkSigningBlockUtils.java b/core/java/android/util/apk/ApkSigningBlockUtils.java
index 9d53847f8110..4146f6fab011 100644
--- a/core/java/android/util/apk/ApkSigningBlockUtils.java
+++ b/core/java/android/util/apk/ApkSigningBlockUtils.java
@@ -306,6 +306,26 @@ final class ApkSigningBlockUtils {
}
/**
+ * Generates the fsverity header and hash tree to be used by kernel for the given apk. This
+ * method does not check whether the root hash exists in the Signing Block or not.
+ *
+ * <p>The output is stored in the {@link ByteBuffer} created by the given {@link
+ * ByteBufferFactory}.
+ *
+ * @return the root hash of the generated hash tree.
+ */
+ public static byte[] generateApkVerity(String apkPath, ByteBufferFactory bufferFactory,
+ SignatureInfo signatureInfo)
+ throws IOException, SignatureNotFoundException, SecurityException, DigestException,
+ NoSuchAlgorithmException {
+ try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
+ ApkVerityBuilder.ApkVerityResult result = ApkVerityBuilder.generateApkVerity(apk,
+ signatureInfo, bufferFactory);
+ return result.rootHash;
+ }
+ }
+
+ /**
* Returns the ZIP End of Central Directory (EoCD) and its offset in the file.
*
* @throws IOException if an I/O error occurs while reading the file.
diff --git a/core/java/android/util/apk/ApkVerityBuilder.java b/core/java/android/util/apk/ApkVerityBuilder.java
index 7412ef411fb4..a0d5e4c2dd8e 100644
--- a/core/java/android/util/apk/ApkVerityBuilder.java
+++ b/core/java/android/util/apk/ApkVerityBuilder.java
@@ -164,11 +164,11 @@ abstract class ApkVerityBuilder {
}
private void fillUpLastOutputChunk() {
- int extra = (int) (BUFFER_SIZE - mOutput.position() % BUFFER_SIZE);
- if (extra == 0) {
+ int lastBlockSize = (int) (mOutput.position() % BUFFER_SIZE);
+ if (lastBlockSize == 0) {
return;
}
- mOutput.put(ByteBuffer.allocate(extra));
+ mOutput.put(ByteBuffer.allocate(BUFFER_SIZE - lastBlockSize));
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index bd22b33f9507..799e3e8d38d0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -155,11 +155,11 @@ public class BatteryStatsImpl extends BatteryStats {
MAX_HISTORY_BUFFER = 96*1024; // 96KB
MAX_MAX_HISTORY_BUFFER = 128*1024; // 128KB
} else {
- MAX_HISTORY_ITEMS = 2000;
- MAX_MAX_HISTORY_ITEMS = 3000;
- MAX_WAKELOCKS_PER_UID = 100;
- MAX_HISTORY_BUFFER = 256*1024; // 256KB
- MAX_MAX_HISTORY_BUFFER = 320*1024; // 256KB
+ MAX_HISTORY_ITEMS = 4000;
+ MAX_MAX_HISTORY_ITEMS = 6000;
+ MAX_WAKELOCKS_PER_UID = 200;
+ MAX_HISTORY_BUFFER = 512*1024; // 512KB
+ MAX_MAX_HISTORY_BUFFER = 640*1024; // 640KB
}
}
diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java
index 66b777e8e8e6..2b5103377ecb 100644
--- a/core/java/com/android/internal/util/DumpUtils.java
+++ b/core/java/com/android/internal/util/DumpUtils.java
@@ -102,6 +102,7 @@ public final class DumpUtils {
case android.os.Process.ROOT_UID:
case android.os.Process.SYSTEM_UID:
case android.os.Process.SHELL_UID:
+ case android.os.Process.INCIDENTD_UID:
return true;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 547e83c144a4..f1b5fdfc2d2a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1747,6 +1747,12 @@
<permission android:name="android.permission.SEND_EMBMS_INTENTS"
android:protectionLevel="signature|privileged" />
+
+ <!-- Allows internal management of the sensor framework
+ @hide -->
+ <permission android:name="android.permission.MANAGE_SENSORS"
+ android:protectionLevel="signature" />
+
<!-- Must be required by an ImsService to ensure that only the
system can bind to it.
<p>Protection level: signature|privileged
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 993bae1eea00..c0633cb44e02 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -165,6 +165,9 @@
<assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
+ <assign-permission name="android.permission.DUMP" uid="incidentd" />
+ <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="incidentd" />
+
<assign-permission name="android.permission.ACCESS_LOWPAN_STATE" uid="lowpan" />
<assign-permission name="android.permission.MANAGE_LOWPAN_INTERFACES" uid="lowpan" />
diff --git a/docs/html/reference/images/text/style/backgroundcolorspan.png b/docs/html/reference/images/text/style/backgroundcolorspan.png
new file mode 100644
index 000000000000..e7e72714c5bb
--- /dev/null
+++ b/docs/html/reference/images/text/style/backgroundcolorspan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/foregroundcolorspan.png b/docs/html/reference/images/text/style/foregroundcolorspan.png
new file mode 100644
index 000000000000..f60db6c55254
--- /dev/null
+++ b/docs/html/reference/images/text/style/foregroundcolorspan.png
Binary files differ
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 0f43db052622..3baf5e4a2d25 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -135,6 +135,7 @@
<uses-permission android:name="android.permission.RESTRICTED_VR_ACCESS" />
<uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE" />
<uses-permission android:name="android.permission.SET_HARMFUL_APP_WARNINGS" />
+ <uses-permission android:name="android.permission.MANAGE_SENSORS" />
<application android:label="@string/app_label"
android:defaultToDeviceProtectedStorage="true"
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 29d33ce777f5..c0c684c41bc5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8601,6 +8601,16 @@ public class ActivityManagerService extends IActivityManager.Stub
}
return false;
}
+
+ @Override
+ public int getPackageUid(String packageName, int flags) {
+ try {
+ return mActivityManagerService.mContext.getPackageManager()
+ .getPackageUid(packageName, flags);
+ } catch (NameNotFoundException nnfe) {
+ return -1;
+ }
+ }
}
class IntentFirewallInterface implements IntentFirewall.AMSInterface {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 7604b6b8f2df..f72104981bc0 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4526,27 +4526,30 @@ public class AudioService extends IAudioService.Stub
if (mStreamType == srcStream.mStreamType) {
return;
}
- synchronized (VolumeStreamState.class) {
- int srcStreamType = srcStream.getStreamType();
- // apply default device volume from source stream to all devices first in case
- // some devices are present in this stream state but not in source stream state
- int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
- index = rescaleIndex(index, srcStreamType, mStreamType);
- for (int i = 0; i < mIndexMap.size(); i++) {
- mIndexMap.put(mIndexMap.keyAt(i), index);
- }
- // Now apply actual volume for devices in source stream state
- SparseIntArray srcMap = srcStream.mIndexMap;
- for (int i = 0; i < srcMap.size(); i++) {
- int device = srcMap.keyAt(i);
- index = srcMap.valueAt(i);
+ synchronized (mSettingsLock) {
+ synchronized (VolumeStreamState.class) {
+ int srcStreamType = srcStream.getStreamType();
+ // apply default device volume from source stream to all devices first in case
+ // some devices are present in this stream state but not in source stream state
+ int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
index = rescaleIndex(index, srcStreamType, mStreamType);
-
- setIndex(index, device, caller);
+ for (int i = 0; i < mIndexMap.size(); i++) {
+ mIndexMap.put(mIndexMap.keyAt(i), index);
+ }
+ // Now apply actual volume for devices in source stream state
+ SparseIntArray srcMap = srcStream.mIndexMap;
+ for (int i = 0; i < srcMap.size(); i++) {
+ int device = srcMap.keyAt(i);
+ index = srcMap.valueAt(i);
+ index = rescaleIndex(index, srcStreamType, mStreamType);
+
+ setIndex(index, device, caller);
+ }
}
}
}
+ @GuardedBy("mSettingsLock")
public void setAllIndexesToMax() {
synchronized (VolumeStreamState.class) {
for (int i = 0; i < mIndexMap.size(); i++) {
diff --git a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
index 4098b989a16b..0504c79c55bd 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
@@ -62,6 +62,11 @@ public class ServiceManagerPermissionTests extends TestCase {
public boolean isRuntimePermission(String permission) {
return false;
}
+
+ @Override
+ public int getPackageUid(String packageName, int flags) {
+ return -1;
+ }
};
ServiceManagerNative.asInterface(BinderInternal.getContextObject())
.setPermissionController(pc);