Merge "Add frequency bucketing to per-thread CPU usage reading"
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 14597ee..550e795 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -6171,6 +6171,7 @@
libcore.reflect.TypeVariableImpl
libcore.reflect.Types
libcore.reflect.WildcardTypeImpl
+libcore.timezone.TimeZoneDataFiles
libcore.util.BasicLruCache
libcore.util.CharsetUtils
libcore.util.CollectionUtils
@@ -6180,7 +6181,6 @@
libcore.util.NativeAllocationRegistry$CleanerThunk
libcore.util.Objects
libcore.util.SneakyThrow
-libcore.util.TimeZoneDataFiles
libcore.util.ZoneInfo
libcore.util.ZoneInfo$CheckedArithmeticException
libcore.util.ZoneInfo$WallTime
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index da4b823..c7184c0 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -382,7 +382,9 @@
/**
* Sets the work source for this thread.
*
- * <p>All the following binder calls on this thread will use the provided work source.
+ * <p>All the following binder calls on this thread will use the provided work source. If this
+ * is called during an on-going binder transaction, all the following binder calls will use the
+ * work source until the end of the transaction.
*
* <p>The concept of worksource is similar to {@link WorkSource}. However, for performance
* reasons, we only support one UID. This UID represents the original user responsible for the
@@ -390,20 +392,20 @@
*
* <p>A typical use case would be
* <pre>
- * Binder.setThreadWorkSource(uid);
+ * long token = Binder.setCallingWorkSourceUid(uid);
* try {
* // Call an API.
* } finally {
- * Binder.clearThreadWorkSource();
+ * Binder.restoreCallingWorkSource(token);
* }
* </pre>
*
* @param workSource The original UID responsible for the binder call.
- * @return The previously set work source.
+ * @return token to restore original work source.
* @hide
**/
@CriticalNative
- public static final native int setThreadWorkSource(int workSource);
+ public static final native long setCallingWorkSourceUid(int workSource);
/**
* Returns the work source set by the caller.
@@ -416,16 +418,34 @@
* @hide
*/
@CriticalNative
- public static final native int getThreadWorkSource();
+ public static final native int getCallingWorkSourceUid();
/**
* Clears the work source on this thread.
*
- * @return The previously set work source.
+ * @return token to restore original work source.
* @hide
**/
@CriticalNative
- public static final native int clearThreadWorkSource();
+ public static final native long clearCallingWorkSource();
+
+ /**
+ * Restores the work source on this thread using a token returned by
+ * {@link #setCallingWorkSourceUid(int) or {@link clearCallingWorkSource()}.
+ *
+ * <p>A typical use case would be
+ * <pre>
+ * long token = Binder.setCallingWorkSourceUid(uid);
+ * try {
+ * // Call an API.
+ * } finally {
+ * Binder.restoreCallingWorkSource(token);
+ * }
+ * </pre>
+ * @hide
+ **/
+ @CriticalNative
+ public static final native void restoreCallingWorkSource(long token);
/**
* Flush any Binder commands pending in the current thread to the kernel
@@ -586,7 +606,7 @@
*
* <li>By default, this listener will propagate the worksource if the outgoing call happens on
* the same thread as the incoming binder call.
- * <li>Custom attribution can be done by calling {@link ThreadLocalWorkSourceUid#set(int)}.
+ * <li>Custom attribution can be done by calling {@link ThreadLocalWorkSource#setUid(int)}.
* @hide
*/
public static class PropagateWorkSourceTransactListener implements ProxyTransactListener {
@@ -595,12 +615,11 @@
// Note that {@link Binder#getCallingUid()} is already set to the UID of the current
// process when this method is called.
//
- // We use ThreadLocalWorkSourceUid instead. It also allows feature owners to set
- // {@link ThreadLocalWorkSourceUid#set(int) manually to attribute resources to a UID.
- int uid = ThreadLocalWorkSourceUid.get();
- if (uid >= 0) {
- int originalUid = Binder.setThreadWorkSource(uid);
- return Integer.valueOf(originalUid);
+ // We use ThreadLocalWorkSource instead. It also allows feature owners to set
+ // {@link ThreadLocalWorkSource#set(int) manually to attribute resources to a UID.
+ int uid = ThreadLocalWorkSource.getUid();
+ if (uid != ThreadLocalWorkSource.UID_NONE) {
+ return Binder.setCallingWorkSourceUid(uid);
}
return null;
}
@@ -608,8 +627,8 @@
@Override
public void onTransactEnded(Object session) {
if (session != null) {
- int uid = (int) session;
- Binder.setThreadWorkSource(uid);
+ long token = (long) session;
+ Binder.restoreCallingWorkSource(token);
}
}
}
@@ -897,11 +916,11 @@
// Log any exceptions as warnings, don't silently suppress them.
// If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
final boolean tracingEnabled = Binder.isTracingEnabled();
+ final long origWorkSource = ThreadLocalWorkSource.setUid(Binder.getCallingUid());
try {
if (tracingEnabled) {
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
}
- ThreadLocalWorkSourceUid.set(Binder.getCallingUid());
res = onTransact(code, data, reply, flags);
} catch (RemoteException|RuntimeException e) {
if (observer != null) {
@@ -922,7 +941,7 @@
}
res = true;
} finally {
- ThreadLocalWorkSourceUid.clear();
+ ThreadLocalWorkSource.restore(origWorkSource);
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index f3a9a50..e8704af 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -739,7 +739,7 @@
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
- msg.workSourceUid = ThreadLocalWorkSourceUid.get();
+ msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 5b8abab..a8d1215 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -204,8 +204,8 @@
if (observer != null) {
token = observer.messageDispatchStarting();
}
+ long origWorkSource = ThreadLocalWorkSource.setUid(msg.workSourceUid);
try {
- ThreadLocalWorkSourceUid.set(msg.workSourceUid);
msg.target.dispatchMessage(msg);
if (observer != null) {
observer.messageDispatched(token, msg);
@@ -217,7 +217,7 @@
}
throw exception;
} finally {
- ThreadLocalWorkSourceUid.clear();
+ ThreadLocalWorkSource.restore(origWorkSource);
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
diff --git a/core/java/android/os/ThreadLocalWorkSourceUid.java b/core/java/android/os/ThreadLocalWorkSource.java
similarity index 64%
rename from core/java/android/os/ThreadLocalWorkSourceUid.java
rename to core/java/android/os/ThreadLocalWorkSource.java
index df1d275..53dd460 100644
--- a/core/java/android/os/ThreadLocalWorkSourceUid.java
+++ b/core/java/android/os/ThreadLocalWorkSource.java
@@ -19,26 +19,41 @@
/**
* @hide Only for use within system server.
*/
-public final class ThreadLocalWorkSourceUid {
+public final class ThreadLocalWorkSource {
public static final int UID_NONE = Message.UID_NONE;
private static final ThreadLocal<Integer> sWorkSourceUid =
ThreadLocal.withInitial(() -> UID_NONE);
/** Returns the original work source uid. */
- public static int get() {
+ public static int getUid() {
return sWorkSourceUid.get();
}
/** Sets the original work source uid. */
- public static void set(int uid) {
+ public static long setUid(int uid) {
+ final long token = getToken();
sWorkSourceUid.set(uid);
+ return token;
+ }
+
+ /** Restores the state using the provided token. */
+ public static void restore(long token) {
+ sWorkSourceUid.set(parseUidFromToken(token));
}
/** Clears the stored work source uid. */
- public static void clear() {
- sWorkSourceUid.set(UID_NONE);
+ public static long clear() {
+ return setUid(UID_NONE);
}
- private ThreadLocalWorkSourceUid() {
+ private static int parseUidFromToken(long token) {
+ return (int) token;
+ }
+
+ private static long getToken() {
+ return sWorkSourceUid.get();
+ }
+
+ private ThreadLocalWorkSource() {
}
}
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 70fc72f..34e8ed4 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -421,7 +421,7 @@
}
protected int getWorkSourceUid() {
- return Binder.getThreadWorkSource();
+ return Binder.getCallingWorkSourceUid();
}
protected long getElapsedRealtimeMicro() {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index fd042b3..4f8bbc1 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -904,19 +904,24 @@
return IPCThreadState::self()->getStrictModePolicy();
}
-static jint android_os_Binder_setThreadWorkSource(jint workSource)
+static jlong android_os_Binder_setCallingWorkSourceUid(jint workSource)
{
- return IPCThreadState::self()->setWorkSource(workSource);
+ return IPCThreadState::self()->setCallingWorkSourceUid(workSource);
}
-static jint android_os_Binder_getThreadWorkSource()
+static jlong android_os_Binder_getCallingWorkSourceUid()
{
- return IPCThreadState::self()->getWorkSource();
+ return IPCThreadState::self()->getCallingWorkSourceUid();
}
-static jint android_os_Binder_clearThreadWorkSource()
+static jlong android_os_Binder_clearCallingWorkSource()
{
- return IPCThreadState::self()->clearWorkSource();
+ return IPCThreadState::self()->clearCallingWorkSource();
+}
+
+static void android_os_Binder_restoreCallingWorkSource(long token)
+{
+ IPCThreadState::self()->restoreCallingWorkSource(token);
}
static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
@@ -962,11 +967,12 @@
// @CriticalNative
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
// @CriticalNative
- { "setThreadWorkSource", "(I)I", (void*)android_os_Binder_setThreadWorkSource },
+ { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid },
// @CriticalNative
- { "getThreadWorkSource", "()I", (void*)android_os_Binder_getThreadWorkSource },
+ { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid },
// @CriticalNative
- { "clearThreadWorkSource", "()I", (void*)android_os_Binder_clearThreadWorkSource },
+ { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
+ { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
{ "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
diff --git a/core/tests/coretests/src/android/os/BinderTest.java b/core/tests/coretests/src/android/os/BinderTest.java
index 1beb598..534c5cd 100644
--- a/core/tests/coretests/src/android/os/BinderTest.java
+++ b/core/tests/coretests/src/android/os/BinderTest.java
@@ -21,17 +21,26 @@
import junit.framework.TestCase;
public class BinderTest extends TestCase {
+ private static final int UID = 100;
@SmallTest
public void testSetWorkSource() throws Exception {
- Binder.setThreadWorkSource(100);
- assertEquals(100, Binder.getThreadWorkSource());
+ Binder.setCallingWorkSourceUid(UID);
+ assertEquals(UID, Binder.getCallingWorkSourceUid());
}
@SmallTest
public void testClearWorkSource() throws Exception {
- Binder.setThreadWorkSource(100);
- Binder.clearThreadWorkSource();
- assertEquals(-1, Binder.getThreadWorkSource());
+ Binder.setCallingWorkSourceUid(UID);
+ Binder.clearCallingWorkSource();
+ assertEquals(-1, Binder.getCallingWorkSourceUid());
+ }
+
+ @SmallTest
+ public void testRestoreWorkSource() throws Exception {
+ Binder.setCallingWorkSourceUid(UID);
+ long token = Binder.clearCallingWorkSource();
+ Binder.restoreCallingWorkSource(token);
+ assertEquals(UID, Binder.getCallingWorkSourceUid());
}
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index c12a5e7..7621ada 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -11,7 +11,7 @@
* 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
+ * limitations under the License.
*/
package com.android.server.backup;
@@ -159,11 +159,12 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
+/** System service that performs backup/restore operations. */
public class BackupManagerService {
public static final String TAG = "BackupManagerService";
public static final boolean DEBUG = true;
public static final boolean MORE_DEBUG = false;
- public static final boolean DEBUG_SCHEDULING = MORE_DEBUG || true;
+ public static final boolean DEBUG_SCHEDULING = true;
// File containing backup-enabled state. Contains a single byte;
// nonzero == enabled. File missing or contains a zero byte == disabled.
@@ -232,8 +233,8 @@
// An entire backup operation spanning multiple packages.
public static final int OP_TYPE_BACKUP = 2;
- // Time delay for initialization operations that can be delayed so as not to consume too much CPU
- // on bring-up and increase time-to-UI.
+ // Time delay for initialization operations that can be delayed so as not to consume too much
+ // CPU on bring-up and increase time-to-UI.
private static final long INITIALIZATION_DELAY_MILLIS = 3000;
// Timeout interval for deciding that a bind or clear-data has taken too long
@@ -327,12 +328,10 @@
private final ArraySet<String> mPendingInits = new ArraySet<>(); // transport names
// map UIDs to the set of participating packages under that UID
- private final SparseArray<HashSet<String>> mBackupParticipants
- = new SparseArray<>();
+ private final SparseArray<HashSet<String>> mBackupParticipants = new SparseArray<>();
// Backups that we haven't started yet. Keys are package names.
- private HashMap<String, BackupRequest> mPendingBackups
- = new HashMap<>();
+ private HashMap<String, BackupRequest> mPendingBackups = new HashMap<>();
// locking around the pending-backup management
private final Object mQueueLock = new Object();
@@ -921,16 +920,16 @@
return null;
}
- final int N = in.readInt();
- schedule = new ArrayList<>(N);
+ final int numPackages = in.readInt();
+ schedule = new ArrayList<>(numPackages);
// HashSet instead of ArraySet specifically because we want the eventual
// lookups against O(hundreds) of entries to be as fast as possible, and
// we discard the set immediately after the scan so the extra memory
// overhead is transient.
- HashSet<String> foundApps = new HashSet<>(N);
+ HashSet<String> foundApps = new HashSet<>(numPackages);
- for (int i = 0; i < N; i++) {
+ for (int i = 0; i < numPackages; i++) {
String pkgName = in.readUTF();
long lastBackup = in.readLong();
foundApps.add(pkgName); // all apps that we've addressed already
@@ -1013,10 +1012,10 @@
// [utf8] package name
// [long] last backup time for this package
// }
- int N = mFullBackupQueue.size();
- bufOut.writeInt(N);
+ int numPackages = mFullBackupQueue.size();
+ bufOut.writeInt(numPackages);
- for (int i = 0; i < N; i++) {
+ for (int i = 0; i < numPackages; i++) {
FullBackupEntry entry = mFullBackupQueue.get(i);
bufOut.writeUTF(entry.packageName);
bufOut.writeLong(entry.lastBackup);
@@ -1056,21 +1055,24 @@
}
}
- // Used for generating random salts or passwords
+ /** Used for generating random salts or passwords. */
public byte[] randomBytes(int bits) {
byte[] array = new byte[bits / 8];
mRng.nextBytes(array);
return array;
}
+ /** For adb backup/restore. */
public boolean setBackupPassword(String currentPw, String newPw) {
return mBackupPasswordManager.setBackupPassword(currentPw, newPw);
}
+ /** For adb backup/restore. */
public boolean hasBackupPassword() {
return mBackupPasswordManager.hasBackupPassword();
}
+ /** For adb backup/restore. */
public boolean backupPasswordMatches(String currentPw) {
return mBackupPasswordManager.backupPasswordMatches(currentPw);
}
@@ -1107,9 +1109,10 @@
}
}
- // Reset all of our bookkeeping, in response to having been told that
- // the backend data has been wiped [due to idle expiry, for example],
- // so we must re-upload all saved settings.
+ /**
+ * Reset all of our bookkeeping because the backend data has been wiped (for example due to idle
+ * expiry), so we must re-upload all saved settings.
+ */
public void resetBackupState(File stateFileDir) {
synchronized (mQueueLock) {
mProcessedPackagesJournal.reset();
@@ -1128,8 +1131,8 @@
// Enqueue a new backup of every participant
synchronized (mBackupParticipants) {
- final int N = mBackupParticipants.size();
- for (int i = 0; i < N; i++) {
+ final int numParticipants = mBackupParticipants.size();
+ for (int i = 0; i < numParticipants; i++) {
HashSet<String> participants = mBackupParticipants.valueAt(i);
if (participants != null) {
for (String packageName : participants) {
@@ -1173,10 +1176,10 @@
boolean added = false;
boolean changed = false;
Bundle extras = intent.getExtras();
- String pkgList[] = null;
- if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
- Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
- Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
+ String[] pkgList = null;
+ if (Intent.ACTION_PACKAGE_ADDED.equals(action)
+ || Intent.ACTION_PACKAGE_REMOVED.equals(action)
+ || Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
Uri uri = intent.getData();
if (uri == null) {
return;
@@ -1369,8 +1372,8 @@
// !!! TODO: cache this and regenerate only when necessary
int flags = PackageManager.GET_SIGNING_CERTIFICATES;
List<PackageInfo> packages = mPackageManager.getInstalledPackages(flags);
- int N = packages.size();
- for (int a = N - 1; a >= 0; a--) {
+ int numPackages = packages.size();
+ for (int a = numPackages - 1; a >= 0; a--) {
PackageInfo pkg = packages.get(a);
try {
ApplicationInfo app = pkg.applicationInfo;
@@ -1393,9 +1396,10 @@
return packages;
}
- // Called from the backup tasks: record that the given app has been successfully
- // backed up at least once. This includes both key/value and full-data backups
- // through the transport.
+ /**
+ * Called from the backup tasks: record that the given app has been successfully backed up at
+ * least once. This includes both key/value and full-data backups through the transport.
+ */
public void logBackupComplete(String packageName) {
if (packageName.equals(PACKAGE_MANAGER_SENTINEL)) return;
@@ -1403,8 +1407,8 @@
final Intent notification = new Intent();
notification.setAction(BACKUP_FINISHED_ACTION);
notification.setPackage(receiver);
- notification.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES |
- Intent.FLAG_RECEIVER_FOREGROUND);
+ notification.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES
+ | Intent.FLAG_RECEIVER_FOREGROUND);
notification.putExtra(BACKUP_FINISHED_PACKAGE_EXTRA, packageName);
mContext.sendBroadcastAsUser(notification, UserHandle.OWNER);
}
@@ -1412,9 +1416,10 @@
mProcessedPackagesJournal.addPackage(packageName);
}
- // Persistently record the current and ancestral backup tokens as well
- // as the set of packages with data [supposedly] available in the
- // ancestral dataset.
+ /**
+ * Persistently record the current and ancestral backup tokens, as well as the set of packages
+ * with data available in the ancestral dataset.
+ */
public void writeRestoreTokens() {
try (RandomAccessFile af = new RandomAccessFile(mTokenFile, "rwd")) {
// First, the version number of this record, for futureproofing
@@ -1468,7 +1473,7 @@
}
// if we timed out with no connect, abort and move on
- if (mConnecting == true) {
+ if (mConnecting) {
Slog.w(TAG, "Timeout waiting for agent " + app);
mConnectedAgent = null;
}
@@ -1489,6 +1494,7 @@
return agent;
}
+ /** Unbind from a backup agent. */
public void unbindAgent(ApplicationInfo app) {
try {
mActivityManager.unbindBackupAgent(app);
@@ -1497,11 +1503,13 @@
}
}
- // clear an application's data, blocking until the operation completes or times out
- // if keepSystemState is true, we intentionally do not also clear system state that
- // would ordinarily also be cleared, because we aren't actually wiping the app back
- // to empty; we're bringing it into the actual expected state related to the already-
- // restored notification state etc.
+ /**
+ * Clear an application's data, blocking until the operation completes or times out. If {@code
+ * keepSystemState} is {@code true}, we intentionally do not clear system state that would
+ * ordinarily also be cleared, because we aren't actually wiping the app back to empty; we're
+ * bringing it into the actual expected state related to the already-restored notification state
+ * etc.
+ */
public void clearApplicationDataSynchronous(String packageName, boolean keepSystemState) {
// Don't wipe packages marked allowClearUserData=false
try {
@@ -1523,7 +1531,8 @@
synchronized (mClearDataLock) {
mClearingData = true;
try {
- mActivityManager.clearApplicationUserData(packageName, keepSystemState, observer, 0);
+ mActivityManager.clearApplicationUserData(
+ packageName, keepSystemState, observer, 0);
} catch (RemoteException e) {
// can't happen because the activity manager is in this process
}
@@ -1541,8 +1550,10 @@
}
}
- // Get the restore-set token for the best-available restore set for this package:
- // the active set if possible, else the ancestral one. Returns zero if none available.
+ /**
+ * Get the restore-set token for the best-available restore set for this {@code packageName}:
+ * the active set if possible, else the ancestral one. Returns zero if none available.
+ */
public long getAvailableRestoreToken(String packageName) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"getAvailableRestoreToken");
@@ -1560,10 +1571,19 @@
return token;
}
+ /**
+ * Requests a backup for the inputted {@code packages}.
+ *
+ * @see #requestBackup(String[], IBackupObserver, IBackupManagerMonitor, int).
+ */
public int requestBackup(String[] packages, IBackupObserver observer, int flags) {
return requestBackup(packages, observer, null, flags);
}
+ /**
+ * Requests a backup for the inputted {@code packages} with a specified {@link
+ * IBackupManagerMonitor}.
+ */
public int requestBackup(String[] packages, IBackupObserver observer,
IBackupManagerMonitor monitor, int flags) {
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup");
@@ -1637,8 +1657,8 @@
EventLog.writeEvent(EventLogTags.BACKUP_REQUESTED, packages.length, kvBackupList.size(),
fullBackupList.size());
if (MORE_DEBUG) {
- Slog.i(TAG, "Backup requested for " + packages.length + " packages, of them: " +
- fullBackupList.size() + " full backups, " + kvBackupList.size()
+ Slog.i(TAG, "Backup requested for " + packages.length + " packages, of them: "
+ + fullBackupList.size() + " full backups, " + kvBackupList.size()
+ " k/v backups");
}
@@ -1651,7 +1671,7 @@
return BackupManager.SUCCESS;
}
- // Cancel all running backups.
+ /** Cancel all running backups. */
public void cancelBackups() {
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "cancelBackups");
if (MORE_DEBUG) {
@@ -1681,11 +1701,12 @@
}
}
+ /** Schedule a timeout message for the operation identified by {@code token}. */
public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
int operationType) {
if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
- Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation " +
- Integer.toHexString(token) + " of type " + operationType);
+ Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation "
+ + Integer.toHexString(token) + " of type " + operationType);
return;
}
if (MORE_DEBUG) {
@@ -1708,12 +1729,16 @@
case OP_TYPE_RESTORE_WAIT:
return MSG_RESTORE_OPERATION_TIMEOUT;
default:
- Slog.wtf(TAG, "getMessageIdForOperationType called on invalid operation type: " +
- operationType);
+ Slog.wtf(TAG, "getMessageIdForOperationType called on invalid operation type: "
+ + operationType);
return -1;
}
}
+ /**
+ * Add an operation to the list of currently running operations. Used for cancellation,
+ * completion and timeout callbacks that act on the operation via the {@code token}.
+ */
public void putOperation(int token, Operation operation) {
if (MORE_DEBUG) {
Slog.d(TAG, "Adding operation token=" + Integer.toHexString(token) + ", operation type="
@@ -1724,20 +1749,24 @@
}
}
+ /**
+ * Remove an operation from the list of currently running operations. An operation is removed
+ * when it is completed, cancelled, or timed out, and thus no longer running.
+ */
public void removeOperation(int token) {
if (MORE_DEBUG) {
Slog.d(TAG, "Removing operation token=" + Integer.toHexString(token));
}
synchronized (mCurrentOpLock) {
if (mCurrentOperations.get(token) == null) {
- Slog.w(TAG, "Duplicate remove for operation. token=" +
- Integer.toHexString(token));
+ Slog.w(TAG, "Duplicate remove for operation. token="
+ + Integer.toHexString(token));
}
mCurrentOperations.remove(token);
}
}
- // synchronous waiter case
+ /** Block until we received an operation complete message (from the agent or cancellation). */
public boolean waitUntilOperationComplete(int token) {
if (MORE_DEBUG) {
Slog.i(TAG, "Blocking until operation complete for "
@@ -1760,8 +1789,8 @@
// When the wait is notified we loop around and recheck the current state
} else {
if (MORE_DEBUG) {
- Slog.d(TAG, "Unblocked waiting for operation token=" +
- Integer.toHexString(token));
+ Slog.d(TAG, "Unblocked waiting for operation token="
+ + Integer.toHexString(token));
}
// No longer pending; we're done
finalState = op.state;
@@ -1782,6 +1811,7 @@
return finalState == OP_ACKNOWLEDGED;
}
+ /** Cancel the operation associated with {@code token}. */
public void handleCancel(int token, boolean cancelAll) {
// Notify any synchronous waiters
Operation op = null;
@@ -1797,8 +1827,8 @@
if (state == OP_ACKNOWLEDGED) {
// The operation finished cleanly, so we have nothing more to do.
if (DEBUG) {
- Slog.w(TAG, "Operation already got an ack." +
- "Should have been removed from mCurrentOperations.");
+ Slog.w(TAG, "Operation already got an ack."
+ + "Should have been removed from mCurrentOperations.");
}
op = null;
mCurrentOperations.delete(token);
@@ -1827,8 +1857,7 @@
}
}
- // ----- Back up a set of applications via a worker thread -----
-
+ /** Returns {@code true} if a backup is currently running, else returns {@code false}. */
public boolean isBackupOperationInProgress() {
synchronized (mCurrentOpLock) {
for (int i = 0; i < mCurrentOperations.size(); i++) {
@@ -1841,7 +1870,7 @@
return false;
}
-
+ /** Unbind the backup agent and kill the app if it's a non-system app. */
public void tearDownAgentAndKill(ApplicationInfo app) {
if (app == null) {
// Null means the system package, so just quietly move on. :)
@@ -1867,6 +1896,7 @@
}
}
+ /** For adb backup/restore. */
public boolean deviceIsEncrypted() {
try {
return mStorageManager.getEncryptionState()
@@ -1917,8 +1947,8 @@
*/
@GuardedBy("mQueueLock")
private void dequeueFullBackupLocked(String packageName) {
- final int N = mFullBackupQueue.size();
- for (int i = N - 1; i >= 0; i--) {
+ final int numPackages = mFullBackupQueue.size();
+ for (int i = numPackages - 1; i >= 0; i--) {
final FullBackupEntry e = mFullBackupQueue.get(i);
if (packageName.equals(e.packageName)) {
mFullBackupQueue.remove(i);
@@ -2167,8 +2197,10 @@
return true;
}
- // The job scheduler says our constraints don't hold any more,
- // so tear down any ongoing backup task right away.
+ /**
+ * The job scheduler says our constraints don't hold anymore, so tear down any ongoing backup
+ * task right away.
+ */
public void endFullBackup() {
// offload the mRunningFullBackupTask.handleCancel() call to another thread,
// as we might have to wait for mCancelLock
@@ -2192,7 +2224,7 @@
new Thread(endFullBackupRunnable, "end-full-backup").start();
}
- // Used by both incremental and full restore
+ /** Used by both incremental and full restore to restore widget data. */
public void restoreWidgetData(String packageName, byte[] widgetData) {
// Apply the restored widget state and generate the ID update for the app
// TODO: http://b/22388012
@@ -2206,6 +2238,7 @@
// NEW UNIFIED RESTORE IMPLEMENTATION
// *****************************
+ /** Schedule a backup pass for {@code packageName}. */
public void dataChangedImpl(String packageName) {
HashSet<String> targets = dataChangedTargets(packageName);
dataChangedImpl(packageName, targets);
@@ -2275,6 +2308,7 @@
// ----- IBackupManager binder interface -----
+ /** Sent from an app's backup agent to let the service know that there's new data to backup. */
public void dataChanged(final String packageName) {
final int callingUserHandle = UserHandle.getCallingUserId();
if (callingUserHandle != UserHandle.USER_SYSTEM) {
@@ -2304,13 +2338,11 @@
});
}
- // Run an initialize operation for the given transport
+ /** Run an initialize operation for the given transport. */
public void initializeTransports(String[] transportNames, IBackupObserver observer) {
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
"initializeTransport");
- if (MORE_DEBUG || true) {
- Slog.v(TAG, "initializeTransport(): " + Arrays.asList(transportNames));
- }
+ Slog.v(TAG, "initializeTransport(): " + Arrays.asList(transportNames));
final long oldId = Binder.clearCallingIdentity();
try {
@@ -2323,7 +2355,7 @@
}
}
- // Clear the given package's backup data from the current transport
+ /** Clear the given package's backup data from the current transport. */
public void clearBackupData(String transportName, String packageName) {
if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
PackageInfo info;
@@ -2377,8 +2409,10 @@
}
}
- // Run a backup pass immediately for any applications that have declared
- // that they have pending updates.
+ /**
+ * Run a backup pass immediately for any applications that have declared that they have pending
+ * updates.
+ */
public void backupNow() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "backupNow");
@@ -2409,17 +2443,18 @@
}
}
+ /** Returns {@code true} if the system user has gone through SUW. */
public boolean deviceIsProvisioned() {
final ContentResolver resolver = mContext.getContentResolver();
return (Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0);
}
- // Run a backup pass for the given packages, writing the resulting data stream
- // to the supplied file descriptor. This method is synchronous and does not return
- // to the caller until the backup has been completed.
- //
- // This is the variant used by 'adb backup'; it requires on-screen confirmation
- // by the user because it can be used to offload data over untrusted USB.
+ /**
+ * Used by 'adb backup' to run a backup pass for packages supplied via the command line, writing
+ * the resulting data stream to the supplied {@code fd}. This method is synchronous and does not
+ * return to the caller until the backup has been completed. It requires on-screen confirmation
+ * by the user.
+ */
public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem,
boolean compress, boolean doKeyValue, String[] pkgList) {
@@ -2497,6 +2532,7 @@
}
}
+ /** Run a full backup pass for the given packages. Used by 'adb shell bmgr'. */
public void fullTransportBackup(String[] pkgNames) {
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
"fullTransportBackup");
@@ -2556,6 +2592,10 @@
}
}
+ /**
+ * Used by 'adb restore' to run a restore pass, blocking until completion. Requires user
+ * confirmation.
+ */
public void adbRestore(ParcelFileDescriptor fd) {
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "adbRestore");
@@ -2639,7 +2679,7 @@
private void waitForCompletion(AdbParams params) {
synchronized (params.latch) {
- while (params.latch.get() == false) {
+ while (!params.latch.get()) {
try {
params.latch.wait();
} catch (InterruptedException e) { /* never interrupted */ }
@@ -2647,6 +2687,7 @@
}
}
+ /** Called when adb backup/restore has completed. */
public void signalAdbBackupRestoreCompletion(AdbParams params) {
synchronized (params.latch) {
params.latch.set(true);
@@ -2654,8 +2695,10 @@
}
}
- // Confirm that the previously-requested full backup/restore operation can proceed. This
- // is used to require a user-facing disclosure about the operation.
+ /**
+ * Confirm that the previously-requested full backup/restore operation can proceed. This is used
+ * to require a user-facing disclosure about the operation.
+ */
public void acknowledgeAdbBackupOrRestore(int token, boolean allow,
String curPassword, String encPpassword, IFullBackupRestoreObserver observer) {
if (DEBUG) {
@@ -2706,7 +2749,7 @@
}
}
- // Enable/disable backups
+ /** User-configurable enabling/disabling of backups. */
public void setBackupEnabled(boolean enable) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"setBackupEnabled");
@@ -2773,7 +2816,7 @@
}
}
- // Enable/disable automatic restore of app data at install time
+ /** Enable/disable automatic restore of app data at install time. */
public void setAutoRestore(boolean doAutoRestore) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"setAutoRestore");
@@ -2792,7 +2835,7 @@
}
}
- // Mark the backup service as having been provisioned
+ /** Mark the backup service as having been provisioned. */
public void setBackupProvisioned(boolean available) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"setBackupProvisioned");
@@ -2801,14 +2844,14 @@
*/
}
- // Report whether the backup mechanism is currently enabled
+ /** Report whether the backup mechanism is currently enabled. */
public boolean isBackupEnabled() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"isBackupEnabled");
return mEnabled; // no need to synchronize just to read it
}
- // Report the name of the currently active transport
+ /** Report the name of the currently active transport. */
public String getCurrentTransport() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"getCurrentTransport");
@@ -2835,7 +2878,7 @@
}
}
- // Report all known, available backup transports
+ /** Report all known, available backup transports by name. */
public String[] listAllTransports() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"listAllTransports");
@@ -2843,12 +2886,14 @@
return mTransportManager.getRegisteredTransportNames();
}
+ /** Report all known, available backup transports by component. */
public ComponentName[] listAllTransportComponents() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"listAllTransportComponents");
return mTransportManager.getRegisteredTransportComponents();
}
+ /** Report all system whitelisted transports. */
public String[] getTransportWhitelist() {
// No permission check, intentionally.
Set<ComponentName> whitelistedComponents = mTransportManager.getTransportWhitelist();
@@ -2947,7 +2992,12 @@
}
}
- /** Selects transport {@code transportName} and returns previous selected transport. */
+ /**
+ * Selects transport {@code transportName} and returns previously selected transport.
+ *
+ * @deprecated Use {@link #selectBackupTransportAsync(ComponentName,
+ * ISelectBackupTransportCallback)} instead.
+ */
@Deprecated
@Nullable
public String selectBackupTransport(String transportName) {
@@ -2966,6 +3016,10 @@
}
}
+ /**
+ * Selects transport {@code transportComponent} asynchronously and notifies {@code listener}
+ * with the result upon completion.
+ */
public void selectBackupTransportAsync(
ComponentName transportComponent, ISelectBackupTransportCallback listener) {
mContext.enforceCallingOrSelfPermission(
@@ -3034,9 +3088,11 @@
}
}
- // Supply the configuration Intent for the given transport. If the name is not one
- // of the available transports, or if the transport does not supply any configuration
- // UI, the method returns null.
+ /**
+ * Supply the configuration intent for the given transport. If the name is not one of the
+ * available transports, or if the transport does not supply any configuration UI, the method
+ * returns {@code null}.
+ */
public Intent getConfigurationIntent(String transportName) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"getConfigurationIntent");
@@ -3077,7 +3133,7 @@
}
}
- // Supply the manage-data intent for the given transport.
+ /** Supply the manage-data intent for the given transport. */
public Intent getDataManagementIntent(String transportName) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"getDataManagementIntent");
@@ -3094,8 +3150,10 @@
}
}
- // Supply the menu label for affordances that fire the manage-data intent
- // for the given transport.
+ /**
+ * Supply the menu label for affordances that fire the manage-data intent for the given
+ * transport.
+ */
public String getDataManagementLabel(String transportName) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"getDataManagementLabel");
@@ -3112,8 +3170,10 @@
}
}
- // Callback: a requested backup agent has been instantiated. This should only
- // be called from the Activity Manager.
+ /**
+ * Callback: a requested backup agent has been instantiated. This should only be called from the
+ * {@link ActivityManager}.
+ */
public void agentConnected(String packageName, IBinder agentBinder) {
synchronized (mAgentConnectLock) {
if (Binder.getCallingUid() == Process.SYSTEM_UID) {
@@ -3129,9 +3189,11 @@
}
}
- // Callback: a backup agent has failed to come up, or has unexpectedly quit.
- // If the agent failed to come up in the first place, the agentBinder argument
- // will be null. This should only be called from the Activity Manager.
+ /**
+ * Callback: a backup agent has failed to come up, or has unexpectedly quit. If the agent failed
+ * to come up in the first place, the agentBinder argument will be {@code null}. This should
+ * only be called from the {@link ActivityManager}.
+ */
public void agentDisconnected(String packageName) {
// TODO: handle backup being interrupted
synchronized (mAgentConnectLock) {
@@ -3146,8 +3208,10 @@
}
}
- // An application being installed will need a restore pass, then the Package Manager
- // will need to be told when the restore is finished.
+ /**
+ * An application being installed will need a restore pass, then the {@link PackageManager} will
+ * need to be told when the restore is finished.
+ */
public void restoreAtInstall(String packageName, int token) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
@@ -3191,8 +3255,8 @@
mWakelock.acquire();
OnTaskFinishedListener listener = caller -> {
- mTransportManager.disposeOfTransportClient(transportClient, caller);
- mWakelock.release();
+ mTransportManager.disposeOfTransportClient(transportClient, caller);
+ mWakelock.release();
};
if (MORE_DEBUG) {
@@ -3232,7 +3296,7 @@
}
}
- // Hand off a restore session
+ /** Hand off a restore session. */
public IRestoreSession beginRestoreSession(String packageName, String transport) {
if (DEBUG) {
Slog.v(TAG, "beginRestoreSession: pkg=" + packageName
@@ -3284,6 +3348,7 @@
return mActiveRestoreSession;
}
+ /** Clear the specified restore session. */
public void clearRestoreSession(ActiveRestoreSession currentSession) {
synchronized (this) {
if (currentSession != mActiveRestoreSession) {
@@ -3296,8 +3361,10 @@
}
}
- // Note that a currently-active backup agent has notified us that it has
- // completed the given outstanding asynchronous backup/restore operation.
+ /**
+ * Note that a currently-active backup agent has notified us that it has completed the given
+ * outstanding asynchronous backup/restore operation.
+ */
public void opComplete(int token, long result) {
if (MORE_DEBUG) {
Slog.v(TAG, "opComplete: " + Integer.toHexString(token) + " result=" + result);
@@ -3313,8 +3380,8 @@
mCurrentOperations.delete(token);
} else if (op.state == OP_ACKNOWLEDGED) {
if (DEBUG) {
- Slog.w(TAG, "Received duplicate ack for token=" +
- Integer.toHexString(token));
+ Slog.w(TAG, "Received duplicate ack for token="
+ + Integer.toHexString(token));
}
op = null;
mCurrentOperations.remove(token);
@@ -3335,6 +3402,7 @@
}
}
+ /** Checks if the package is eligible for backup. */
public boolean isAppEligibleForBackup(String packageName) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BACKUP, "isAppEligibleForBackup");
@@ -3356,6 +3424,7 @@
}
}
+ /** Returns the inputted packages that are eligible for backup. */
public String[] filterAppsEligibleForBackup(String[] packages) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BACKUP, "filterAppsEligibleForBackup");
@@ -3382,6 +3451,7 @@
}
}
+ /** Prints service state for 'dumpsys backup'. */
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
@@ -3478,9 +3548,9 @@
pw.print("Current: ");
pw.println(Long.toHexString(mCurrentToken));
- int N = mBackupParticipants.size();
+ int numPackages = mBackupParticipants.size();
pw.println("Participants:");
- for (int i = 0; i < N; i++) {
+ for (int i = 0; i < numPackages; i++) {
int uid = mBackupParticipants.keyAt(i);
pw.print(" uid: ");
pw.println(uid);
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 580e4f4..3a74ab5 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -42,7 +42,6 @@
import com.android.server.pm.PackageDexOptimizer;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.PackageManagerServiceUtils;
-import com.android.server.pm.PackageManagerServiceCompilerMapping;
import java.io.File;
import java.io.IOException;
diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
index a7a7686..de3c9f2 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
@@ -18,8 +18,6 @@
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
-import android.annotation.Nullable;
-
/**
* Options used for dexopt invocations.
*/
diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
index d2600b5..9a12a2f 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
@@ -24,8 +24,6 @@
import com.android.server.pm.PackageDexOptimizer;
import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
public final class DexoptUtils {
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index 86f7380..519a20d 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -35,13 +35,10 @@
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
index 23c4a337..c4d2851 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerService.java
@@ -47,6 +47,7 @@
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import libcore.icu.ICU;
+import libcore.timezone.TzDataSetVersion;
import libcore.util.TimeZoneFinder;
import libcore.util.ZoneInfoDB;
@@ -66,8 +67,8 @@
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
static final DistroFormatVersion DISTRO_FORMAT_VERSION_SUPPORTED =
new DistroFormatVersion(
- DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
- DistroVersion.CURRENT_FORMAT_MINOR_VERSION);
+ TzDataSetVersion.currentFormatMajorVersion(),
+ TzDataSetVersion.currentFormatMinorVersion());
public static class Lifecycle extends SystemService {
public Lifecycle(Context context) {
diff --git a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
index c4cb593..25d1cc7 100644
--- a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -11,7 +11,7 @@
* 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
+ * limitations under the License.
*/
package com.android.server.backup;
@@ -75,6 +75,7 @@
import java.io.File;
import java.util.List;
+/** Tests for the system service {@link BackupManagerService} that performs backup/restore. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowAppBackupUtils.class})
@Presubmit
@@ -94,6 +95,10 @@
private String mTransportName;
private ShadowPackageManager mShadowPackageManager;
+ /**
+ * Initialize state that {@link BackupManagerService} operations interact with. This includes
+ * setting up the transport, starting the backup thread, and creating backup data directories.
+ */
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -119,12 +124,20 @@
mDataDir = new File(cacheDir, "data");
}
+ /**
+ * Clean up and reset state that was created for testing {@link BackupManagerService}
+ * operations.
+ */
@After
public void tearDown() throws Exception {
mBackupThread.quit();
ShadowAppBackupUtils.reset();
}
+ /**
+ * Test verifying that {@link BackupManagerService#MORE_DEBUG} is set to {@code false}. This is
+ * specifically to prevent overloading the logs in production.
+ */
@Test
public void testMoreDebug_isFalse() throws Exception {
boolean moreDebug = BackupManagerService.MORE_DEBUG;
@@ -132,8 +145,10 @@
assertThat(moreDebug).isFalse();
}
- /* Tests for destination string */
-
+ /**
+ * Test verifying that {@link BackupManagerService#getDestinationString(String)} returns the
+ * current destination string of inputted transport if the transport is registered.
+ */
@Test
public void testDestinationString() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -146,6 +161,10 @@
assertThat(destination).isEqualTo("destinationString");
}
+ /**
+ * Test verifying that {@link BackupManagerService#getDestinationString(String)} returns {@code
+ * null} if the inputted transport is not registered.
+ */
@Test
public void testDestinationString_whenTransportNotRegistered() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -158,6 +177,10 @@
assertThat(destination).isNull();
}
+ /**
+ * Test verifying that {@link BackupManagerService#getDestinationString(String)} throws a {@link
+ * SecurityException} if the caller does not have backup permission.
+ */
@Test
public void testDestinationString_withoutPermission() throws Exception {
mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
@@ -170,8 +193,10 @@
() -> backupManagerService.getDestinationString(mTransportName));
}
- /* Tests for app eligibility */
-
+ /**
+ * Test verifying that {@link BackupManagerService#isAppEligibleForBackup(String)} returns
+ * {@code false} when the given app is not eligible for backup.
+ */
@Test
public void testIsAppEligibleForBackup_whenAppNotEligible() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -183,6 +208,10 @@
assertThat(result).isFalse();
}
+ /**
+ * Test verifying that {@link BackupManagerService#isAppEligibleForBackup(String)} returns
+ * {@code true} when the given app is eligible for backup.
+ */
@Test
public void testIsAppEligibleForBackup_whenAppEligible() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -197,6 +226,10 @@
.disposeOfTransportClient(eq(transportMock.transportClient), any());
}
+ /**
+ * Test verifying that {@link BackupManagerService#isAppEligibleForBackup(String)} throws a
+ * {@link SecurityException} if the caller does not have backup permission.
+ */
@Test
public void testIsAppEligibleForBackup_withoutPermission() throws Exception {
mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
@@ -209,6 +242,11 @@
() -> backupManagerService.isAppEligibleForBackup(PACKAGE_1));
}
+ /**
+ * Test verifying that {@link BackupManagerService#filterAppsEligibleForBackup(String[])}
+ * returns an {@code array} of only apps that are eligible for backup from an {@array} of
+ * inputted apps.
+ */
@Test
public void testFilterAppsEligibleForBackup() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -225,6 +263,10 @@
.disposeOfTransportClient(eq(transportMock.transportClient), any());
}
+ /**
+ * Test verifying that {@link BackupManagerService#filterAppsEligibleForBackup(String[])}
+ * returns an empty {@code array} if no inputted apps are eligible for backup.
+ */
@Test
public void testFilterAppsEligibleForBackup_whenNoneIsEligible() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -237,6 +279,10 @@
assertThat(filtered).isEmpty();
}
+ /**
+ * Test verifying that {@link BackupManagerService#filterAppsEligibleForBackup(String[])} throws
+ * a {@link SecurityException} if the caller does not have backup permission.
+ */
@Test
public void testFilterAppsEligibleForBackup_withoutPermission() throws Exception {
mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
@@ -270,6 +316,11 @@
.thenReturn(mOldTransport.transportName);
}
+ /**
+ * Test verifying that {@link BackupManagerService#selectBackupTransport(String)} successfully
+ * switches the current transport to the inputted transport, returns the name of the old
+ * transport, and disposes of the transport client after the operation.
+ */
@Test
public void testSelectBackupTransport() throws Exception {
setUpForSelectTransport();
@@ -285,6 +336,10 @@
.disposeOfTransportClient(eq(mNewTransportMock.transportClient), any());
}
+ /**
+ * Test verifying that {@link BackupManagerService#selectBackupTransport(String)} throws a
+ * {@link SecurityException} if the caller does not have backup permission.
+ */
@Test
public void testSelectBackupTransport_withoutPermission() throws Exception {
setUpForSelectTransport();
@@ -296,6 +351,11 @@
() -> backupManagerService.selectBackupTransport(mNewTransport.transportName));
}
+ /**
+ * Test verifying that {@link BackupManagerService#selectBackupTransportAsync(ComponentName,
+ * ISelectBackupTransportCallback)} successfully switches the current transport to the inputted
+ * transport and disposes of the transport client after the operation.
+ */
@Test
public void testSelectBackupTransportAsync() throws Exception {
setUpForSelectTransport();
@@ -314,6 +374,12 @@
.disposeOfTransportClient(eq(mNewTransportMock.transportClient), any());
}
+ /**
+ * Test verifying that {@link BackupManagerService#selectBackupTransportAsync(ComponentName,
+ * ISelectBackupTransportCallback)} does not switch the current transport to the inputted
+ * transport and notifies the inputted callback of failure when it fails to register the
+ * transport.
+ */
@Test
public void testSelectBackupTransportAsync_whenRegistrationFails() throws Exception {
setUpForSelectTransport();
@@ -330,6 +396,11 @@
verify(callback).onFailure(anyInt());
}
+ /**
+ * Test verifying that {@link BackupManagerService#selectBackupTransportAsync(ComponentName,
+ * ISelectBackupTransportCallback)} does not switch the current transport to the inputted
+ * transport and notifies the inputted callback of failure when the transport gets unregistered.
+ */
@Test
public void testSelectBackupTransportAsync_whenTransportGetsUnregistered() throws Exception {
setUpTransports(mTransportManager, mTransport.unregistered());
@@ -347,6 +418,11 @@
verify(callback).onFailure(anyInt());
}
+ /**
+ * Test verifying that {@link BackupManagerService#selectBackupTransportAsync(ComponentName,
+ * ISelectBackupTransportCallback)} throws a {@link SecurityException} if the caller does not
+ * have backup permission.
+ */
@Test
public void testSelectBackupTransportAsync_withoutPermission() throws Exception {
setUpForSelectTransport();
@@ -366,8 +442,10 @@
mContext.getContentResolver(), Settings.Secure.BACKUP_TRANSPORT);
}
- /* Tests for transport attributes */
-
+ /**
+ * Test verifying that {@link BackupManagerService#getCurrentTransportComponent()} returns the
+ * {@link ComponentName} of the currently selected transport.
+ */
@Test
public void testGetCurrentTransportComponent() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -380,6 +458,10 @@
assertThat(transportComponent).isEqualTo(mTransport.getTransportComponent());
}
+ /**
+ * Test verifying that {@link BackupManagerService#getCurrentTransportComponent()} returns
+ * {@code null} if there is no currently selected transport.
+ */
@Test
public void testGetCurrentTransportComponent_whenNoTransportSelected() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -391,6 +473,10 @@
assertThat(transportComponent).isNull();
}
+ /**
+ * Test verifying that {@link BackupManagerService#getCurrentTransportComponent()} returns
+ * {@code null} if the currently selected transport is not registered.
+ */
@Test
public void testGetCurrentTransportComponent_whenTransportNotRegistered() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -403,6 +489,10 @@
assertThat(transportComponent).isNull();
}
+ /**
+ * Test verifying that {@link BackupManagerService#getCurrentTransportComponent()} throws a
+ * {@link SecurityException} if the caller does not have backup permission.
+ */
@Test
public void testGetCurrentTransportComponent_withoutPermission() throws Exception {
mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
@@ -428,9 +518,14 @@
mTransportUid = mContext.getPackageManager().getPackageUid(transportPackage, 0);
}
+ /**
+ * Test verifying that {@link BackupManagerService#updateTransportAttributes(int, ComponentName,
+ * String, Intent, String, Intent, String)} succeeds if the uid of the transport is same as the
+ * uid of the caller.
+ */
@Test
public void
- testUpdateTransportAttributes_whenTransportUidEqualsToCallingUid_callsThroughToTransportManager()
+ testUpdateTransportAttributes_whenTransportUidEqualsCallingUid_callsTransportManager()
throws Exception {
setUpForUpdateTransportAttributes();
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -457,6 +552,11 @@
eq("dataManagementLabel"));
}
+ /**
+ * Test verifying that {@link BackupManagerService#updateTransportAttributes(int, ComponentName,
+ * String, Intent, String, Intent, String)} throws a {@link SecurityException} if the uid of the
+ * transport is not equal to the uid of the caller.
+ */
@Test
public void testUpdateTransportAttributes_whenTransportUidNotEqualToCallingUid_throwsException()
throws Exception {
@@ -477,6 +577,11 @@
"dataManagementLabel"));
}
+ /**
+ * Test verifying that {@link BackupManagerService#updateTransportAttributes(int, ComponentName,
+ * String, Intent, String, Intent, String)} throws a {@link RuntimeException} if given a {@code
+ * null} transport component.
+ */
@Test
public void testUpdateTransportAttributes_whenTransportComponentNull_throwsException()
throws Exception {
@@ -497,6 +602,11 @@
"dataManagementLabel"));
}
+ /**
+ * Test verifying that {@link BackupManagerService#updateTransportAttributes(int, ComponentName,
+ * String, Intent, String, Intent, String)} throws a {@link RuntimeException} if given a {@code
+ * null} transport name.
+ */
@Test
public void testUpdateTransportAttributes_whenNameNull_throwsException() throws Exception {
setUpForUpdateTransportAttributes();
@@ -516,6 +626,11 @@
"dataManagementLabel"));
}
+ /**
+ * Test verifying that {@link BackupManagerService#updateTransportAttributes(int, ComponentName,
+ * String, Intent, String, Intent, String)} throws a {@link RuntimeException} if given a {@code
+ * null} destination string.
+ */
@Test
public void testUpdateTransportAttributes_whenCurrentDestinationStringNull_throwsException()
throws Exception {
@@ -536,9 +651,14 @@
"dataManagementLabel"));
}
+ /**
+ * Test verifying that {@link BackupManagerService#updateTransportAttributes(int, ComponentName,
+ * String, Intent, String, Intent, String)} throws a {@link RuntimeException} if given either a
+ * {@code null} data management label or {@code null} data management intent, but not both.
+ */
@Test
public void
- testUpdateTransportAttributes_whenDataManagementArgumentsNullityDontMatch_throwsException()
+ testUpdateTransportAttributes_whenDataManagementArgsNullityDontMatch_throwsException()
throws Exception {
setUpForUpdateTransportAttributes();
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -569,6 +689,10 @@
null));
}
+ /**
+ * Test verifying that {@link BackupManagerService#updateTransportAttributes(int, ComponentName,
+ * String, Intent, String, Intent, String)} succeeds if the caller has backup permission.
+ */
@Test
public void testUpdateTransportAttributes_whenPermissionGranted_callsThroughToTransportManager()
throws Exception {
@@ -597,6 +721,11 @@
eq("dataManagementLabel"));
}
+ /**
+ * Test verifying that {@link BackupManagerService#updateTransportAttributes(int, ComponentName,
+ * String, Intent, String, Intent, String)} throws a {@link SecurityException} if the caller
+ * does not have backup permission.
+ */
@Test
public void testUpdateTransportAttributes_whenPermissionDenied_throwsSecurityException()
throws Exception {
@@ -634,6 +763,10 @@
ShadowKeyValueBackupTask.reset();
}
+ /**
+ * Test verifying that {@link BackupManagerService#requestBackup(String[], IBackupObserver,
+ * int)} throws a {@link SecurityException} if the caller does not have backup permission.
+ */
@Test
public void testRequestBackup_whenPermissionDenied() throws Exception {
mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
@@ -644,6 +777,10 @@
() -> backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0));
}
+ /**
+ * Test verifying that {@link BackupManagerService#requestBackup(String[], IBackupObserver,
+ * int)} throws an {@link IllegalArgumentException} if passed {@null} for packages.
+ */
@Test
public void testRequestBackup_whenPackagesNull() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -655,6 +792,11 @@
verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
}
+ /**
+ * Test verifying that {@link BackupManagerService#requestBackup(String[], IBackupObserver,
+ * int)} throws an {@link IllegalArgumentException} if passed an empty {@code array} for
+ * packages.
+ */
@Test
public void testRequestBackup_whenPackagesEmpty() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -666,6 +808,10 @@
verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
}
+ /**
+ * Test verifying that {@link BackupManagerService#requestBackup(String[], IBackupObserver,
+ * int)} returns {@link BackupManager#ERROR_BACKUP_NOT_ALLOWED} if backup is disabled.
+ */
@Test
public void testRequestBackup_whenBackupDisabled() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -678,6 +824,11 @@
verify(mObserver).backupFinished(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
}
+ /**
+ * Test verifying that {@link BackupManagerService#requestBackup(String[], IBackupObserver,
+ * int)} returns {@link BackupManager#ERROR_BACKUP_NOT_ALLOWED} if the system user hasn't gone
+ * through SUW.
+ */
@Test
public void testRequestBackup_whenNotProvisioned() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -690,6 +841,11 @@
verify(mObserver).backupFinished(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
}
+ /**
+ * Test verifying that {@link BackupManagerService#requestBackup(String[], IBackupObserver,
+ * int)} returns {@link BackupManager#ERROR_TRANSPORT_ABORTED} if the current transport is not
+ * registered.
+ */
@Test
public void testRequestBackup_whenTransportNotRegistered() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -704,6 +860,11 @@
verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
}
+ /**
+ * Test verifying that {@link BackupManagerService#requestBackup(String[], IBackupObserver,
+ * int)} returns {@link BackupManager#SUCCESS} and notifies the observer of {@link
+ * BackupManager#ERROR_BACKUP_NOT_ALLOWED} if the specified app is not eligible for backup.
+ */
@Test
public void testRequestBackup_whenAppNotEligibleForBackup() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -722,6 +883,11 @@
tearDownForRequestBackup();
}
+ /**
+ * Test verifying that {@link BackupManagerService#requestBackup(String[], IBackupObserver,
+ * int)} returns {@link BackupManager#SUCCESS} and updates bookkeeping if backup for a key value
+ * package succeeds.
+ */
@Test
@Config(shadows = ShadowKeyValueBackupTask.class)
public void testRequestBackup_whenPackageIsKeyValue() throws Exception {
@@ -739,6 +905,11 @@
tearDownForRequestBackup();
}
+ /**
+ * Test verifying that {@link BackupManagerService#requestBackup(String[], IBackupObserver,
+ * int)} returns {@link BackupManager#SUCCESS} and updates bookkeeping if backup for a full
+ * backup package succeeds.
+ */
@Test
@Config(shadows = ShadowKeyValueBackupTask.class)
public void testRequestBackup_whenPackageIsFullBackup() throws Exception {
@@ -757,6 +928,10 @@
tearDownForRequestBackup();
}
+ /**
+ * Test verifying that {@link BackupManagerService#backupNow()} clears the calling identity
+ * for scheduling a job and then restores the original calling identity after the operation.
+ */
@Test
@Config(shadows = {ShadowBinder.class, ShadowKeyValueBackupJob.class})
public void testBackupNow_clearsCallingIdentityForJobScheduler() {
@@ -771,6 +946,10 @@
assertThat(ShadowBinder.getCallingUid()).isEqualTo(1);
}
+ /**
+ * Test verifying that {@link BackupManagerService#backupNow()} restores the original calling
+ * identity if an exception is thrown during execution.
+ */
@Test
@Config(shadows = {ShadowBinder.class, ShadowKeyValueBackupJobException.class})
public void testBackupNow_whenExceptionThrown_restoresCallingIdentity() {
@@ -792,8 +971,11 @@
return backupManagerService;
}
- /* Miscellaneous tests */
-
+ /**
+ * Test verifying that {@link BackupManagerService#BackupManagerService(Context, Trampoline,
+ * HandlerThread, File, File, TransportManager)} posts a transport registration task to the
+ * backup handler thread.
+ */
@Test
public void testConstructor_postRegisterTransports() {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -804,6 +986,11 @@
verify(mTransportManager).registerTransports();
}
+ /**
+ * Test verifying that the {@link BackupManagerService#BackupManagerService(Context, Trampoline,
+ * HandlerThread, File, File, TransportManager)} does not directly register transports in its
+ * own thread.
+ */
@Test
public void testConstructor_doesNotRegisterTransportsSynchronously() {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
@@ -842,6 +1029,10 @@
*/
@Implements(KeyValueBackupJob.class)
public static class ShadowKeyValueBackupJobException extends ShadowKeyValueBackupJob {
+ /**
+ * Implementation of {@link ShadowKeyValueBackupJob#schedule(Context, long,
+ * BackupManagerConstants)} that throws an {@link IllegalArgumentException}.
+ */
public static void schedule(Context ctx, long delay, BackupManagerConstants constants) {
ShadowKeyValueBackupJob.schedule(ctx, delay, constants);
throw new IllegalArgumentException();
diff --git a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
index c252609..1b106dd 100644
--- a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
@@ -40,6 +40,7 @@
import javax.annotation.Nullable;
import libcore.io.IoUtils;
+import libcore.timezone.TzDataSetVersion;
import static com.android.server.timezone.RulesManagerService.REQUIRED_QUERY_PERMISSION;
import static com.android.server.timezone.RulesManagerService.REQUIRED_UPDATER_PERMISSION;
@@ -128,15 +129,15 @@
configureDeviceSystemRulesVersion("2016a");
DistroVersion stagedDistroVersion = new DistroVersion(
- DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
- DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
+ TzDataSetVersion.currentFormatMajorVersion(),
+ TzDataSetVersion.currentFormatMinorVersion() - 1,
"2016c",
3);
configureStagedInstall(stagedDistroVersion);
DistroVersion installedDistroVersion = new DistroVersion(
- DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
- DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
+ TzDataSetVersion.currentFormatMajorVersion(),
+ TzDataSetVersion.currentFormatMinorVersion() - 1,
"2016b",
4);
configureInstalledDistroVersion(installedDistroVersion);
@@ -162,8 +163,8 @@
configureNoStagedOperation();
DistroVersion installedDistroVersion = new DistroVersion(
- DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
- DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
+ TzDataSetVersion.currentFormatMajorVersion(),
+ TzDataSetVersion.currentFormatMinorVersion() - 1,
"2016b",
4);
configureInstalledDistroVersion(installedDistroVersion);
@@ -187,8 +188,8 @@
configureStagedUninstall();
DistroVersion installedDistroVersion = new DistroVersion(
- DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
- DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
+ TzDataSetVersion.currentFormatMajorVersion(),
+ TzDataSetVersion.currentFormatMinorVersion() - 1,
"2016b",
4);
configureInstalledDistroVersion(installedDistroVersion);
@@ -231,8 +232,8 @@
configureDeviceCannotReadStagedDistroOperation();
DistroVersion installedDistroVersion = new DistroVersion(
- DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
- DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
+ TzDataSetVersion.currentFormatMajorVersion(),
+ TzDataSetVersion.currentFormatMinorVersion() - 1,
"2016b",
4);
configureInstalledDistroVersion(installedDistroVersion);
@@ -275,8 +276,8 @@
configureDeviceSystemRulesVersion(systemRulesVersion);
DistroVersion installedDistroVersion = new DistroVersion(
- DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
- DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
+ TzDataSetVersion.currentFormatMajorVersion(),
+ TzDataSetVersion.currentFormatMinorVersion() - 1,
installedRulesVersion,
revision);
configureInstalledDistroVersion(installedDistroVersion);