Merge "Introduce audio playback capture API"
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index d78647e..62926cb 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -5630,7 +5630,7 @@
* frameworks/base/packages/SystemUI/
*/
message AssistGestureStageReported {
- optional android.hardware.sensor.assist.AssistGestureStageEnum gesture_stage = 1;
+ optional android.hardware.sensor.assist.AssistGestureStageEnum gesture_stage = 1;
}
/**
@@ -5640,8 +5640,8 @@
* frameworks/base/packages/SystemUI/
*/
message AssistGestureFeedbackReported {
- // Whether or not the gesture was used.
- optional android.hardware.sensor.assist.AssistGestureFeedbackEnum feedback_type = 1;
+ // Whether or not the gesture was used.
+ optional android.hardware.sensor.assist.AssistGestureFeedbackEnum feedback_type = 1;
}
/**
@@ -5651,8 +5651,8 @@
* frameworks/base/packages/SystemUI/
*/
message AssistGestureProgressReported {
- // [0,100] progress for the assist gesture.
- optional int32 progress = 1;
+ // [0,100] progress for the assist gesture.
+ optional int32 progress = 1;
}
/*
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 1de8117..de378b0 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -398,8 +398,8 @@
}
}
- /**
- * See com.android.internal.os.SystemZygoteInit.readArgumentList()
+ /*
+ * See com.android.internal.os.ZygoteArguments.parseArgs()
* Presently the wire format to the zygote process is:
* a) a count of arguments (argc, in essence)
* b) a number of newline-separated argument strings equal to count
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 22884ac..0604ab2 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -767,17 +767,6 @@
* @throws IOException passed straight through
*/
static String[] readArgumentList(BufferedReader socketReader) throws IOException {
-
- /**
- * See android.os.Process.zygoteSendArgsAndGetPid()
- * Presently the wire format to the zygote process is:
- * a) a count of arguments (argc, in essence)
- * b) a number of newline-separated argument strings equal to count
- *
- * After the zygote process reads these it will write the pid of
- * the child or -1 on failure.
- */
-
int argc;
try {
diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java
index e6bcd37..c24a9e0 100644
--- a/core/java/com/android/internal/os/ZygoteArguments.java
+++ b/core/java/com/android/internal/os/ZygoteArguments.java
@@ -217,8 +217,17 @@
* Per security review bug #1112214, duplicate args are disallowed in critical cases to make
* injection harder.
*/
- private void parseArgs(String[] args)
- throws IllegalArgumentException {
+ private void parseArgs(String[] args) throws IllegalArgumentException {
+ /*
+ * See android.os.ZygoteProcess.zygoteSendArgsAndGetResult()
+ * Presently the wire format to the zygote process is:
+ * a) a count of arguments (argc, in essence)
+ * b) a number of newline-separated argument strings equal to count
+ *
+ * After the zygote process reads these it will write the pid of
+ * the child or -1 on failure.
+ */
+
int curArg = 0;
boolean seenRuntimeArgs = false;
diff --git a/core/proto/android/hardware/sensor/assist/enums.proto b/core/proto/android/hardware/sensor/assist/enums.proto
index 8c5841a..012dcb2 100644
--- a/core/proto/android/hardware/sensor/assist/enums.proto
+++ b/core/proto/android/hardware/sensor/assist/enums.proto
@@ -21,14 +21,14 @@
option java_multiple_files = true;
enum AssistGestureStageEnum {
- ASSIST_GESTURE_STAGE_UNKNOWN = 0;
- ASSIST_GESTURE_STAGE_PROGRESS = 1;
- ASSIST_GESTURE_STAGE_PRIMED = 2;
- ASSIST_GESTURE_STAGE_DETECTED = 3;
+ ASSIST_GESTURE_STAGE_UNKNOWN = 0;
+ ASSIST_GESTURE_STAGE_PROGRESS = 1;
+ ASSIST_GESTURE_STAGE_PRIMED = 2;
+ ASSIST_GESTURE_STAGE_DETECTED = 3;
}
enum AssistGestureFeedbackEnum {
- ASSIST_GESTURE_FEEDBACK_UNKNOWN = 0;
- ASSIST_GESTURE_FEEDBACK_NOT_USED = 1;
- ASSIST_GESTURE_FEEDBACK_USED = 2;
+ ASSIST_GESTURE_FEEDBACK_UNKNOWN = 0;
+ ASSIST_GESTURE_FEEDBACK_NOT_USED = 1;
+ ASSIST_GESTURE_FEEDBACK_USED = 2;
}
\ No newline at end of file
diff --git a/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java b/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java
index 8077431..efa4387 100644
--- a/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java
+++ b/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java
@@ -16,25 +16,21 @@
package com.android.systemui.notifications;
+import android.app.ActivityManager;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
-import android.app.ActivityManager;
import android.car.Car;
import android.car.CarNotConnectedException;
import android.car.drivingstate.CarUxRestrictionsManager;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.os.ServiceManager;
-import android.os.UserHandle;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.GestureDetector;
@@ -95,28 +91,12 @@
private static int sSettleOpenPercentage;
private static int sSettleClosePercentage;
- private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_USER_SWITCHED)) {
- mCarNotificationListener.registerAsSystemService(mContext,
- mCarUxRestrictionManagerWrapper,
- mClickHandlerFactory);
- inflateNotificationContent();
- }
- }
- };
-
/**
* Inits the window that hosts the notifications and establishes the connections
* to the car related services.
*/
@Override
public void start() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_USER_SWITCHED);
- mContext.registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter, null, null);
sSettleOpenPercentage = mContext.getResources().getInteger(
R.integer.notification_settle_open_percentage);
sSettleClosePercentage = mContext.getResources().getInteger(
@@ -133,11 +113,12 @@
ServiceManager.getService(Context.STATUS_BAR_SERVICE)),
launchResult -> {
if (launchResult == ActivityManager.START_TASK_TO_FRONT
- || launchResult == ActivityManager.START_SUCCESS) {
+ || launchResult == ActivityManager.START_SUCCESS){
closeCarNotifications(DEFAULT_FLING_VELOCITY);
}
});
-
+ mCarNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper,
+ mClickHandlerFactory);
mCar = Car.createCar(mContext, mCarConnectionListener);
mCar.connect();
NotificationGestureListener gestureListener = new NotificationGestureListener();
@@ -150,6 +131,8 @@
mCarNotificationWindow
.setBackgroundColor(mContext.getColor(R.color.notification_shade_background_color));
+ inflateNotificationContent();
+
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY,
@@ -220,7 +203,7 @@
// There's a view installed at a higher z-order such that we can intercept the ACTION_DOWN
// to set the initial click state.
mCarNotificationWindow.findViewById(R.id.glass_pane).setOnTouchListener((v, event) -> {
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+ if (event.getActionMasked() == MotionEvent.ACTION_UP ) {
mNotificationListAtBottomAtTimeOfTouch = false;
}
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
@@ -271,7 +254,7 @@
public boolean onTouch(View v, MotionEvent event) {
// reset mNotificationListAtBottomAtTimeOfTouch here since the "glass pane" will not
// get the up event
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+ if (event.getActionMasked() == MotionEvent.ACTION_UP ) {
mNotificationListAtBottomAtTimeOfTouch = false;
}
boolean wasScrolledUp = mScrollUpDetector.onTouchEvent(event);
@@ -355,7 +338,7 @@
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH
- || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) {
+ || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY){
// swipe was not vertical or was not fast enough
return false;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b1c186e..9ff2f44 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -15835,6 +15835,12 @@
if (reconciledPkg.prepareResult.replace) {
PackageParser.Package oldPackage = mPackages.get(packageName);
+
+ // Set the update and install times
+ PackageSetting deletedPkgSetting = (PackageSetting) oldPackage.mExtras;
+ setInstallAndUpdateTime(pkg, deletedPkgSetting.firstInstallTime,
+ System.currentTimeMillis());
+
if (reconciledPkg.prepareResult.system) {
// Remove existing system package
removePackageLI(oldPackage, true);
@@ -15850,11 +15856,6 @@
res.removedInfo.args = null;
}
- // Set the update and install times
- PackageSetting deletedPkgSetting = (PackageSetting) oldPackage.mExtras;
- setInstallAndUpdateTime(pkg, deletedPkgSetting.firstInstallTime,
- System.currentTimeMillis());
-
// Update the package dynamic state if succeeded
// Now that the install succeeded make sure we remove data
// directories for any child package the update removed.
diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
index 8d9b3cf..fe4825c 100644
--- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
+++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
@@ -23,12 +23,14 @@
import static org.testng.Assert.assertEquals;
import android.app.usage.EventList;
+import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents.Event;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.res.Configuration;
import android.test.suitebuilder.annotation.SmallTest;
+import android.util.AtomicFile;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -38,6 +40,7 @@
import org.junit.runner.RunWith;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
@@ -448,4 +451,45 @@
runBackupRestoreTest(0);
runBackupRestoreTest(99999);
}
+
+ /**
+ * Test the pruning in indexFilesLocked() that only allow up to 100 daily files, 50 weekly files
+ * , 12 monthly files, 10 yearly files.
+ */
+ @Test
+ public void testMaxFiles() throws IOException {
+ final File[] intervalDirs = new File[]{
+ new File(mTestDir, "daily"),
+ new File(mTestDir, "weekly"),
+ new File(mTestDir, "monthly"),
+ new File(mTestDir, "yearly"),
+ };
+ // Create 10 extra files under each interval dir.
+ final int extra = 10;
+ final int length = intervalDirs.length;
+ for (int i = 0; i < length; i++) {
+ final int numFiles = UsageStatsDatabase.MAX_FILES_PER_INTERVAL_TYPE[i] + extra;
+ for (int f = 0; f < numFiles; f++) {
+ final AtomicFile file = new AtomicFile(new File(intervalDirs[i], Long.toString(f)));
+ FileOutputStream fos = file.startWrite();
+ fos.write(1);
+ file.finishWrite(fos);
+ }
+ }
+ // indexFilesLocked() list files under each interval dir, if number of files are more than
+ // the max allowed files for each interval type, it deletes the lowest numbered files.
+ mUsageStatsDatabase.forceIndexFiles();
+ final int len = mUsageStatsDatabase.mSortedStatFiles.length;
+ for (int i = 0; i < len; i++) {
+ final TimeSparseArray<AtomicFile> files = mUsageStatsDatabase.mSortedStatFiles[i];
+ // The stats file for each interval type equals to max allowed.
+ assertEquals(UsageStatsDatabase.MAX_FILES_PER_INTERVAL_TYPE[i],
+ files.size());
+ // The highest numbered file,
+ assertEquals(UsageStatsDatabase.MAX_FILES_PER_INTERVAL_TYPE[i] + extra - 1,
+ files.keyAt(files.size() - 1));
+ // The lowest numbered file:
+ assertEquals(extra, files.keyAt(0));
+ }
+ }
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 0e15947..dff6809 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -43,8 +43,8 @@
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
@@ -84,6 +84,9 @@
@VisibleForTesting
public static final int BACKUP_VERSION = 4;
+ @VisibleForTesting
+ static final int[] MAX_FILES_PER_INTERVAL_TYPE = new int[]{100, 50, 12, 10};
+
// Key under which the payload blob is stored
// same as UsageStatsBackupHelper.KEY_USAGE_STATS
static final String KEY_USAGE_STATS = "usage_stats";
@@ -104,7 +107,8 @@
private final Object mLock = new Object();
private final File[] mIntervalDirs;
- private final TimeSparseArray<AtomicFile>[] mSortedStatFiles;
+ @VisibleForTesting
+ final TimeSparseArray<AtomicFile>[] mSortedStatFiles;
private final UnixCalendar mCal;
private final File mVersionFile;
private final File mBackupsDir;
@@ -126,10 +130,10 @@
@VisibleForTesting
public UsageStatsDatabase(File dir, int version) {
mIntervalDirs = new File[]{
- new File(dir, "daily"),
- new File(dir, "weekly"),
- new File(dir, "monthly"),
- new File(dir, "yearly"),
+ new File(dir, "daily"),
+ new File(dir, "weekly"),
+ new File(dir, "monthly"),
+ new File(dir, "yearly"),
};
mCurrentVersion = version;
mVersionFile = new File(dir, "version");
@@ -248,6 +252,14 @@
return true;
}
+ /** @hide */
+ @VisibleForTesting
+ void forceIndexFiles() {
+ synchronized (mLock) {
+ indexFilesLocked();
+ }
+ }
+
private void indexFilesLocked() {
final FilenameFilter backupFileFilter = new FilenameFilter() {
@Override
@@ -255,7 +267,6 @@
return !name.endsWith(BAK_SUFFIX);
}
};
-
// Index the available usage stat files on disk.
for (int i = 0; i < mSortedStatFiles.length; i++) {
if (mSortedStatFiles[i] == null) {
@@ -268,8 +279,9 @@
if (DEBUG) {
Slog.d(TAG, "Found " + files.length + " stat files for interval " + i);
}
-
- for (File f : files) {
+ final int len = files.length;
+ for (int j = 0; j < len; j++) {
+ final File f = files[j];
final AtomicFile af = new AtomicFile(f);
try {
mSortedStatFiles[i].put(parseBeginTime(af), af);
@@ -277,6 +289,16 @@
Slog.e(TAG, "failed to index file: " + f, e);
}
}
+
+ // only keep the max allowed number of files for each interval type.
+ final int toDelete = mSortedStatFiles[i].size() - MAX_FILES_PER_INTERVAL_TYPE[i];
+ if (toDelete > 0) {
+ for (int j = 0; j < toDelete; j++) {
+ mSortedStatFiles[i].valueAt(0).delete();
+ mSortedStatFiles[i].removeAt(0);
+ }
+ Slog.d(TAG, "Deleted " + toDelete + " stat files for interval " + i);
+ }
}
}
}
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 3cb2216..ebd8e36 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -595,8 +595,8 @@
private void loadActiveStats(final long currentTimeMillis) {
for (int intervalType = 0; intervalType < mCurrentStats.length; intervalType++) {
final IntervalStats stats = mDatabase.getLatestUsageStats(intervalType);
- if (stats != null && currentTimeMillis - 500 >= stats.endTime &&
- currentTimeMillis < stats.beginTime + INTERVAL_LENGTH[intervalType]) {
+ if (stats != null
+ && currentTimeMillis < stats.beginTime + INTERVAL_LENGTH[intervalType]) {
if (DEBUG) {
Slog.d(TAG, mLogPrefix + "Loading existing stats @ " +
sDateFormat.format(stats.beginTime) + "(" + stats.beginTime +