summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/input/InputReader.h3
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java65
-rw-r--r--services/java/com/android/server/am/ActivityStack.java2
-rw-r--r--services/java/com/android/server/am/ActivityStackSupervisor.java4
-rw-r--r--services/java/com/android/server/content/SyncManager.java9
-rw-r--r--services/java/com/android/server/content/SyncStorageEngine.java439
-rw-r--r--services/java/com/android/server/wifi/WifiService.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java13
8 files changed, 284 insertions, 257 deletions
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 98daaf5..a8bb636 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -1285,6 +1285,9 @@ protected:
if (haveSizeBias) {
*outSize += sizeBias;
}
+ if (*outSize < 0) {
+ *outSize = 0;
+ }
}
} mCalibration;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index be6119d..3f58fa4 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -21,12 +21,12 @@ import static com.android.internal.util.XmlUtils.readIntAttribute;
import static com.android.internal.util.XmlUtils.writeIntAttribute;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
-
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
import android.app.AppOpsManager;
import android.appwidget.AppWidgetManager;
import android.util.ArrayMap;
+
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
@@ -52,6 +52,7 @@ import com.android.server.pm.UserManagerService;
import com.android.server.wm.AppTransition;
import com.android.server.wm.StackBox;
import com.android.server.wm.WindowManagerService;
+
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
@@ -154,6 +155,7 @@ import android.os.UpdateLock;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.format.Time;
+import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.EventLog;
import android.util.Log;
@@ -536,7 +538,7 @@ public final class ActivityManagerService extends ActivityManagerNative
* This is the process holding what we currently consider to be
* the "home" activity.
*/
- ProcessRecord mHomeProcess;
+ ArraySet<ProcessRecord> mHomeProcess = new ArraySet<ProcessRecord>();
/**
* This is the process holding the activity the user last visited that
@@ -8951,11 +8953,11 @@ public final class ActivityManagerService extends ActivityManagerNative
// replaced by a third-party app, clear the package preferred activities from packages
// with a home activity running in the process to prevent a repeatedly crashing app
// from blocking the user to manually clear the list.
- if (app == mHomeProcess && mHomeProcess.activities.size() > 0
- && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
- Iterator<ActivityRecord> it = mHomeProcess.activities.iterator();
- while (it.hasNext()) {
- ActivityRecord r = it.next();
+ final ArrayList<ActivityRecord> activities = app.activities;
+ if (mHomeProcess.contains(app) && activities.size() > 0
+ && (app.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+ final ActivityRecord r = activities.get(activityNdx);
if (r.isHomeActivity()) {
Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
try {
@@ -10230,13 +10232,20 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
}
}
- if (mHomeProcess != null && (dumpPackage == null
- || mHomeProcess.pkgList.containsKey(dumpPackage))) {
- if (needSep) {
- pw.println();
- needSep = false;
+ if (!mHomeProcess.isEmpty()) {
+ final int size = mHomeProcess.size();
+ ProcessRecord[] processes = new ProcessRecord[size];
+ mHomeProcess.toArray(processes);
+ for (int processNdx = 0; processNdx < size; ++processNdx) {
+ final ProcessRecord app = processes[processNdx];
+ if (dumpPackage == null || app.pkgList.containsKey(dumpPackage)) {
+ if (needSep) {
+ pw.println();
+ needSep = false;
+ }
+ pw.println(" mHomeProcess[" + processNdx + "]: " + app);
+ }
}
- pw.println(" mHomeProcess: " + mHomeProcess);
}
if (mPreviousProcess != null && (dumpPackage == null
|| mPreviousProcess.pkgList.containsKey(dumpPackage))) {
@@ -11737,10 +11746,10 @@ public final class ActivityManagerService extends ActivityManagerNative
}
return inLaunching;
}
-
+
/**
* Main code for cleaning up a process when it has gone away. This is
- * called both as a result of the process dying, or directly when stopping
+ * called both as a result of the process dying, or directly when stopping
* a process when running in single process mode.
*/
private final void cleanUpApplicationRecordLocked(ProcessRecord app,
@@ -11751,7 +11760,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mProcessesToGc.remove(app);
mPendingPssProcesses.remove(app);
-
+
// Dismiss any open dialogs.
if (app.crashDialog != null && !app.forceCrashReport) {
app.crashDialog.dismiss();
@@ -11768,7 +11777,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.crashing = false;
app.notResponding = false;
-
+
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
app.thread = null;
@@ -11801,7 +11810,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (checkAppInLaunchingProvidersLocked(app, false)) {
restart = true;
}
-
+
// Unregister from connected content providers.
if (!app.conProviders.isEmpty()) {
for (int i=0; i<app.conProviders.size(); i++) {
@@ -11828,7 +11837,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
-
+
skipCurrentReceiverLocked(app);
// Unregister any receivers.
@@ -11859,6 +11868,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
+ mHomeProcess.remove(app);
+
// If the caller is restarting this app, then leave it in its
// current lists and let the caller take care of it.
if (restarting) {
@@ -11888,8 +11899,8 @@ public final class ActivityManagerService extends ActivityManagerNative
"Clean-up removing on hold: " + app);
mProcessesOnHold.remove(app);
- if (app == mHomeProcess) {
- mHomeProcess = null;
+ if (mHomeProcess.contains(app)) {
+ mHomeProcess.remove(app);
}
if (app == mPreviousProcess) {
mPreviousProcess = null;
@@ -13815,7 +13826,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- if (app == mHomeProcess) {
+ if (mHomeProcess.contains(app)) {
if (adj > ProcessList.HOME_APP_ADJ) {
// This process is hosting what we currently consider to be the
// home app, so we don't want to let it go into the background.
@@ -13882,7 +13893,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
procState = ActivityManager.PROCESS_STATE_SERVICE;
}
- if (app.hasShownUi && app != mHomeProcess) {
+ if (app.hasShownUi && !mHomeProcess.contains(app)) {
// If this process has shown some UI, let it immediately
// go to the LRU list because it may be pretty heavy with
// UI stuff. We'll tag it with a label just to help
@@ -13945,7 +13956,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
// Not doing bind OOM management, so treat
// this guy more like a started service.
- if (app.hasShownUi && app != mHomeProcess) {
+ if (app.hasShownUi && !mHomeProcess.contains(app)) {
// If this process has shown some UI, let it immediately
// go to the LRU list because it may be pretty heavy with
// UI stuff. We'll tag it with a label just to help
@@ -14000,7 +14011,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// about letting this process get into the LRU
// list to be killed and restarted if needed for
// memory.
- if (app.hasShownUi && app != mHomeProcess
+ if (app.hasShownUi && !mHomeProcess.contains(app)
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
adjType = "cch-bound-ui-services";
} else {
@@ -14114,7 +14125,7 @@ public final class ActivityManagerService extends ActivityManagerNative
clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
}
if (adj > clientAdj) {
- if (app.hasShownUi && app != mHomeProcess
+ if (app.hasShownUi && !mHomeProcess.contains(app)
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
app.adjType = "cch-ui-provider";
} else {
@@ -14974,7 +14985,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// to be good enough at this point that destroying
// activities causes more harm than good.
if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
- && app != mHomeProcess && app != mPreviousProcess) {
+ && !mHomeProcess.contains(app) && app != mPreviousProcess) {
// Need to do this on its own message because the stack may not
// be in a consistent state at this point.
// For these apps we will also finish their activities
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index a0bbfad..2fefadf 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2246,7 +2246,7 @@ final class ActivityStack {
if (r.state == ActivityState.RESUMED
|| r.state == ActivityState.PAUSING
|| r.state == ActivityState.PAUSED) {
- if (!r.isHomeActivity() || mService.mHomeProcess != r.app) {
+ if (!r.isHomeActivity() || !mService.mHomeProcess.contains(r.app)) {
Slog.w(TAG, " Force finishing activity "
+ r.intent.getComponent().flattenToShortString());
finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 0808861..250ab4a 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -905,7 +905,7 @@ public final class ActivityStackSupervisor {
r.task.taskId, r.shortComponentName);
}
if (r.isHomeActivity() && r.isNotResolverActivity()) {
- mService.mHomeProcess = app;
+ mService.mHomeProcess.add(app);
}
mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
r.sleeping = false;
@@ -1946,7 +1946,7 @@ public final class ActivityStackSupervisor {
// makes sense to.
if (r.app != null && fgApp != null && r.app != fgApp
&& r.lastVisibleTime > mService.mPreviousProcessVisibleTime
- && r.app != mService.mHomeProcess) {
+ && !mService.mHomeProcess.contains(r.app)) {
mService.mPreviousProcess = r.app;
mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
}
diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java
index ee5b890..a6b69a2 100644
--- a/services/java/com/android/server/content/SyncManager.java
+++ b/services/java/com/android/server/content/SyncManager.java
@@ -2889,11 +2889,12 @@ public class SyncManager {
// determine if we need to set or cancel the alarm
boolean shouldSet = false;
boolean shouldCancel = false;
- final boolean alarmIsActive = mAlarmScheduleTime != null;
+ final boolean alarmIsActive = (mAlarmScheduleTime != null) && (now < mAlarmScheduleTime);
final boolean needAlarm = alarmTime != Long.MAX_VALUE;
if (needAlarm) {
- // Need the alarm if it's currently not set, or if our time is before the currently
- // set time.
+ // Need the alarm if
+ // - it's currently not set
+ // - if the alarm is set in the past.
if (!alarmIsActive || alarmTime < mAlarmScheduleTime) {
shouldSet = true;
}
@@ -2910,7 +2911,7 @@ public class SyncManager {
+ " secs from now");
}
mAlarmScheduleTime = alarmTime;
- mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime,
+ mAlarmService.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime,
mSyncAlarmIntent);
} else if (shouldCancel) {
mAlarmScheduleTime = null;
diff --git a/services/java/com/android/server/content/SyncStorageEngine.java b/services/java/com/android/server/content/SyncStorageEngine.java
index 25529a6..e3693f8 100644
--- a/services/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/java/com/android/server/content/SyncStorageEngine.java
@@ -53,6 +53,7 @@ import org.xmlpull.v1.XmlSerializer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
@@ -71,7 +72,7 @@ public class SyncStorageEngine extends Handler {
private static final String TAG = "SyncManager";
private static final boolean DEBUG = true;
- private static final boolean DEBUG_FILE = true;
+ private static final String TAG_FILE = "SyncManagerFile";
private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId";
private static final String XML_ATTR_LISTEN_FOR_TICKLES = "listen-for-tickles";
@@ -420,9 +421,12 @@ public class SyncStorageEngine extends Handler {
File systemDir = new File(dataDir, "system");
File syncDir = new File(systemDir, "sync");
syncDir.mkdirs();
+
+ maybeDeleteLegacyPendingInfoLocked(syncDir);
+
mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
mStatusFile = new AtomicFile(new File(syncDir, "status.bin"));
- mPendingFile = new AtomicFile(new File(syncDir, "pending.bin"));
+ mPendingFile = new AtomicFile(new File(syncDir, "pending.xml"));
mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin"));
readAccountInfoLocked();
@@ -676,7 +680,8 @@ public class SyncStorageEngine extends Handler {
continue;
}
for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
- if (providerName != null && !providerName.equals(authorityInfo.authority)) {
+ if (providerName != null
+ && !providerName.equals(authorityInfo.authority)) {
continue;
}
if (authorityInfo.backoffTime != nextSyncTime
@@ -774,10 +779,12 @@ public class SyncStorageEngine extends Handler {
}
synchronized (mAuthorities) {
if (toUpdate.period <= 0 && add) {
- Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-" + add);
+ Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-"
+ + add);
}
if (toUpdate.extras == null) {
- Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-" + add);
+ Log.e(TAG, "null extras, should never happen in updateOrRemovePeriodicSync: add-"
+ + add);
}
try {
AuthorityInfo authority =
@@ -806,7 +813,7 @@ public class SyncStorageEngine extends Handler {
if (!alreadyPresent) {
authority.periodicSyncs.add(new PeriodicSync(toUpdate));
SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
- status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0);
+ status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0L);
}
} else {
// Remove any periodic syncs that match the authority and extras.
@@ -824,7 +831,8 @@ public class SyncStorageEngine extends Handler {
if (status != null) {
status.removePeriodicSyncTime(i);
} else {
- Log.e(TAG, "Tried removing sync status on remove periodic sync but did not find it.");
+ Log.e(TAG, "Tried removing sync status on remove periodic sync but"
+ + "did not find it.");
}
} else {
i++;
@@ -942,7 +950,7 @@ public class SyncStorageEngine extends Handler {
op = new PendingOperation(op);
op.authorityId = authority.ident;
mPendingOperations.add(op);
- writePendingOperationsLocked();
+ appendPendingOperationLocked(op);
SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
status.pending = true;
@@ -1660,7 +1668,9 @@ public class SyncStorageEngine extends Handler {
FileInputStream fis = null;
try {
fis = mAccountInfoFile.openRead();
- if (DEBUG_FILE) Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile());
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile());
+ }
XmlPullParser parser = Xml.newPullParser();
parser.setInput(fis, null);
int eventType = parser.getEventType();
@@ -1745,6 +1755,20 @@ public class SyncStorageEngine extends Handler {
}
/**
+ * Ensure the old pending.bin is deleted, as it has been changed to pending.xml.
+ * pending.xml was used starting in KLP.
+ * @param syncDir directory where the sync files are located.
+ */
+ private void maybeDeleteLegacyPendingInfoLocked(File syncDir) {
+ File file = new File(syncDir, "pending.bin");
+ if (!file.exists()) {
+ return;
+ } else {
+ file.delete();
+ }
+ }
+
+ /**
* some authority names have changed. copy over their settings and delete the old ones
* @return true if a change was made
*/
@@ -1832,18 +1856,21 @@ public class SyncStorageEngine extends Handler {
syncable = "unknown";
}
authority = mAuthorities.get(id);
- if (DEBUG_FILE) Log.v(TAG, "Adding authority: account="
- + accountName + " auth=" + authorityName
- + " user=" + userId
- + " enabled=" + enabled
- + " syncable=" + syncable);
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Adding authority: account="
+ + accountName + " auth=" + authorityName
+ + " user=" + userId
+ + " enabled=" + enabled
+ + " syncable=" + syncable);
+ }
if (authority == null) {
- if (DEBUG_FILE) {
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
Log.v(TAG, "Creating entry");
}
if (accountName != null && accountType != null) {
authority = getOrCreateAuthorityLocked(
- new Account(accountName, accountType), userId, authorityName, id, false);
+ new Account(accountName, accountType), userId, authorityName, id,
+ false);
} else {
authority = getOrCreateAuthorityLocked(
new ComponentName(packageName, className), userId, id, false);
@@ -1943,7 +1970,9 @@ public class SyncStorageEngine extends Handler {
* Write all account information to the account file.
*/
private void writeAccountInfoLocked() {
- if (DEBUG_FILE) Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile());
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile());
+ }
FileOutputStream fos = null;
try {
@@ -2041,7 +2070,9 @@ public class SyncStorageEngine extends Handler {
final boolean hasType = db.getVersion() >= 11;
// Copy in all of the status information, as well as accounts.
- if (DEBUG_FILE) Log.v(TAG, "Reading legacy sync accounts db");
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Reading legacy sync accounts db");
+ }
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables("stats, status");
HashMap<String,String> map = new HashMap<String,String>();
@@ -2151,7 +2182,9 @@ public class SyncStorageEngine extends Handler {
* Read all sync status back in to the initial engine state.
*/
private void readStatusLocked() {
- if (DEBUG_FILE) Log.v(TAG, "Reading " + mStatusFile.getBaseFile());
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Reading " + mStatusFile.getBaseFile());
+ }
try {
byte[] data = mStatusFile.readFully();
Parcel in = Parcel.obtain();
@@ -2163,8 +2196,10 @@ public class SyncStorageEngine extends Handler {
SyncStatusInfo status = new SyncStatusInfo(in);
if (mAuthorities.indexOfKey(status.authorityId) >= 0) {
status.pending = false;
- if (DEBUG_FILE) Log.v(TAG, "Adding status for id "
- + status.authorityId);
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Adding status for id "
+ + status.authorityId);
+ }
mSyncStatus.put(status.authorityId, status);
}
} else {
@@ -2182,7 +2217,9 @@ public class SyncStorageEngine extends Handler {
* Write all sync status to the sync status file.
*/
private void writeStatusLocked() {
- if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatusFile.getBaseFile());
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Writing new " + mStatusFile.getBaseFile());
+ }
// The file is being written, so we don't need to have a scheduled
// write until the next change.
@@ -2211,103 +2248,97 @@ public class SyncStorageEngine extends Handler {
}
}
- public static final int PENDING_OPERATION_VERSION = 4;
+ public static final int PENDING_OPERATION_VERSION = 3;
- /**
- * Read all pending operations back in to the initial engine state.
- */
+ /** Read all pending operations back in to the initial engine state. */
private void readPendingOperationsLocked() {
- if (DEBUG_FILE) Log.v(TAG, "Reading " + mPendingFile.getBaseFile());
- try {
- readPendingAsXml();
- } catch (XmlPullParserException e) {
- Log.d(TAG, "Error parsing pending as xml, trying as parcel.");
- try {
- readPendingAsParcelled();
- } catch (java.io.IOException e1) {
- Log.i(TAG, "No initial pending operations");
+ FileInputStream fis = null;
+ if (!mPendingFile.getBaseFile().exists()) {
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG_FILE, "No pending operation file.");
+ return;
}
}
- }
-
- private void readPendingAsXml() throws XmlPullParserException {
- FileInputStream fis = null;
try {
fis = mPendingFile.openRead();
- XmlPullParser parser = Xml.newPullParser();
+ XmlPullParser parser;
+ parser = Xml.newPullParser();
parser.setInput(fis, null);
+
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG &&
eventType != XmlPullParser.END_DOCUMENT) {
eventType = parser.next();
}
- if (eventType == XmlPullParser.END_DOCUMENT) return;
+ if (eventType == XmlPullParser.END_DOCUMENT) return; // Nothing to read.
String tagName = parser.getName();
- if ("pending".equals(tagName)) {
- int version = -1;
- String versionString = parser.getAttributeValue(null, "version");
- if (versionString == null ||
- Integer.parseInt(versionString) != PENDING_OPERATION_VERSION) {
- Log.w(TAG, "Unknown pending operation version "
- + version + "; trying to read as binary.");
- throw new XmlPullParserException("Unknown version.");
- }
- eventType = parser.next();
+ do {
PendingOperation pop = null;
- do {
- if (eventType == XmlPullParser.START_TAG) {
- try {
- tagName = parser.getName();
- if (parser.getDepth() == 2 && "op".equals(tagName)) {
- int authorityId = Integer.valueOf(parser.getAttributeValue(
- null, XML_ATTR_AUTHORITYID));
- boolean expedited = Boolean.valueOf(parser.getAttributeValue(
- null, XML_ATTR_EXPEDITED));
- int syncSource = Integer.valueOf(parser.getAttributeValue(
- null, XML_ATTR_SOURCE));
- int reason = Integer.valueOf(parser.getAttributeValue(
- null, XML_ATTR_REASON));
- AuthorityInfo authority = mAuthorities.get(authorityId);
- if (DEBUG_FILE) {
- Log.v(TAG, authorityId + " " + expedited + " " + syncSource + " " + reason);
- }
- if (authority != null) {
- pop = new PendingOperation(
- authority.account, authority.userId, reason, syncSource,
- authority.authority, new Bundle(), expedited);
- pop.authorityId = authorityId;
- pop.flatExtras = null; // No longer used.
- mPendingOperations.add(pop);
- if (DEBUG_FILE) Log.v(TAG, "Adding pending op: account=" + pop.account
- + " auth=" + pop.authority
+ if (eventType == XmlPullParser.START_TAG) {
+ try {
+ tagName = parser.getName();
+ if (parser.getDepth() == 1 && "op".equals(tagName)) {
+ // Verify version.
+ String versionString =
+ parser.getAttributeValue(null, XML_ATTR_VERSION);
+ if (versionString == null ||
+ Integer.parseInt(versionString) != PENDING_OPERATION_VERSION) {
+ Log.w(TAG, "Unknown pending operation version " + versionString);
+ throw new java.io.IOException("Unknown version.");
+ }
+ int authorityId = Integer.valueOf(parser.getAttributeValue(
+ null, XML_ATTR_AUTHORITYID));
+ boolean expedited = Boolean.valueOf(parser.getAttributeValue(
+ null, XML_ATTR_EXPEDITED));
+ int syncSource = Integer.valueOf(parser.getAttributeValue(
+ null, XML_ATTR_SOURCE));
+ int reason = Integer.valueOf(parser.getAttributeValue(
+ null, XML_ATTR_REASON));
+ AuthorityInfo authority = mAuthorities.get(authorityId);
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG_FILE, authorityId + " " + expedited + " " + syncSource + " "
+ + reason);
+ }
+ if (authority != null) {
+ pop = new PendingOperation(
+ authority.account, authority.userId, reason,
+ syncSource, authority.authority, new Bundle(),
+ expedited);
+ pop.flatExtras = null; // No longer used.
+ mPendingOperations.add(pop);
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG_FILE, "Adding pending op: "
+ + pop.authority
+ " src=" + pop.syncSource
+ " reason=" + pop.reason
+ " expedited=" + pop.expedited);
- } else {
- // Skip non-existent authority;
- pop = null;
- if (DEBUG_FILE) {
- Log.v(TAG, "No authority found for " + authorityId
- + ", skipping");
- }
}
- } else if (parser.getDepth() == 3 &&
- pop != null &&
- "extra".equals(tagName)) {
- parseExtra(parser, pop.extras);
+ } else {
+ // Skip non-existent authority.
+ pop = null;
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG_FILE, "No authority found for " + authorityId
+ + ", skipping");
+ }
}
- } catch (NumberFormatException e) {
- Log.d(TAG, "Invalid data in xml file.", e);
+ } else if (parser.getDepth() == 2 &&
+ pop != null &&
+ "extra".equals(tagName)) {
+ parseExtra(parser, pop.extras);
}
+ } catch (NumberFormatException e) {
+ Log.d(TAG, "Invalid data in xml file.", e);
}
- eventType = parser.next();
- } while(eventType != XmlPullParser.END_DOCUMENT);
- }
+ }
+ eventType = parser.next();
+ } while(eventType != XmlPullParser.END_DOCUMENT);
} catch (java.io.IOException e) {
- if (fis == null) Log.i(TAG, "No initial pending operations.");
- else Log.w(TAG, "Error reading pending data.", e);
- return;
+ Log.w(TAG_FILE, "Error reading pending data.", e);
+ } catch (XmlPullParserException e) {
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.w(TAG_FILE, "Error parsing pending ops xml.", e);
+ }
} finally {
if (fis != null) {
try {
@@ -2316,60 +2347,99 @@ public class SyncStorageEngine extends Handler {
}
}
}
+
+ private static final String XML_ATTR_AUTHORITYID = "authority_id";
+ private static final String XML_ATTR_SOURCE = "source";
+ private static final String XML_ATTR_EXPEDITED = "expedited";
+ private static final String XML_ATTR_REASON = "reason";
+ private static final String XML_ATTR_VERSION = "version";
+
/**
- * Old format of reading pending.bin as a parcelled file. Replaced in lieu of JSON because
- * persisting parcels is unsafe.
- * @throws java.io.IOException
+ * Write all currently pending ops to the pending ops file.
*/
- private void readPendingAsParcelled() throws java.io.IOException {
- byte[] data = mPendingFile.readFully();
- Parcel in = Parcel.obtain();
- in.unmarshall(data, 0, data.length);
- in.setDataPosition(0);
- final int SIZE = in.dataSize();
- while (in.dataPosition() < SIZE) {
- int version = in.readInt();
- if (version != 3 && version != 1) {
- Log.w(TAG, "Unknown pending operation version "
- + version + "; dropping all ops");
- break;
- }
- int authorityId = in.readInt();
- int syncSource = in.readInt();
- byte[] flatExtras = in.createByteArray();
- boolean expedited;
- if (version == PENDING_OPERATION_VERSION) {
- expedited = in.readInt() != 0;
- } else {
- expedited = false;
- }
- int reason = in.readInt();
- AuthorityInfo authority = mAuthorities.get(authorityId);
- if (authority != null) {
- Bundle extras;
- if (flatExtras != null) {
- extras = unflattenBundle(flatExtras);
- } else {
- // if we are unable to parse the extras for whatever reason convert this
- // to a regular sync by creating an empty extras
- extras = new Bundle();
+ private void writePendingOperationsLocked() {
+ final int N = mPendingOperations.size();
+ FileOutputStream fos = null;
+ try {
+ if (N == 0) {
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG_FILE, "Truncating " + mPendingFile.getBaseFile());
}
- PendingOperation op = new PendingOperation(
- authority.account, authority.userId, reason, syncSource,
- authority.authority, extras, expedited);
- op.authorityId = authorityId;
- op.flatExtras = flatExtras;
- if (DEBUG_FILE) Log.v(TAG, "Adding pending op: account=" + op.account
- + " auth=" + op.authority
- + " src=" + op.syncSource
- + " reason=" + op.reason
- + " expedited=" + op.expedited
- + " extras=" + op.extras);
- mPendingOperations.add(op);
+ mPendingFile.truncate();
+ return;
+ }
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG_FILE, "Writing new " + mPendingFile.getBaseFile());
+ }
+ fos = mPendingFile.startWrite();
+ XmlSerializer out = new FastXmlSerializer();
+ out.setOutput(fos, "utf-8");
+
+ for (int i = 0; i < N; i++) {
+ PendingOperation pop = mPendingOperations.get(i);
+ writePendingOperationLocked(pop, out);
+ }
+ out.endDocument();
+ mPendingFile.finishWrite(fos);
+ } catch (java.io.IOException e1) {
+ Log.w(TAG, "Error writing pending operations", e1);
+ if (fos != null) {
+ mPendingFile.failWrite(fos);
}
}
}
+ /** Write all currently pending ops to the pending ops file. */
+ private void writePendingOperationLocked(PendingOperation pop, XmlSerializer out)
+ throws IOException {
+ // Pending operation.
+ out.startTag(null, "op");
+
+ out.attribute(null, XML_ATTR_VERSION, Integer.toString(PENDING_OPERATION_VERSION));
+ out.attribute(null, XML_ATTR_AUTHORITYID, Integer.toString(pop.authorityId));
+ out.attribute(null, XML_ATTR_SOURCE, Integer.toString(pop.syncSource));
+ out.attribute(null, XML_ATTR_EXPEDITED, Boolean.toString(pop.expedited));
+ out.attribute(null, XML_ATTR_REASON, Integer.toString(pop.reason));
+ extrasToXml(out, pop.extras);
+
+ out.endTag(null, "op");
+ }
+
+ /**
+ * Append the given operation to the pending ops file; if unable to,
+ * write all pending ops.
+ */
+ private void appendPendingOperationLocked(PendingOperation op) {
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Appending to " + mPendingFile.getBaseFile());
+ }
+ FileOutputStream fos = null;
+ try {
+ fos = mPendingFile.openAppend();
+ } catch (java.io.IOException e) {
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Failed append; writing full file");
+ }
+ writePendingOperationsLocked();
+ return;
+ }
+
+ try {
+ XmlSerializer out = new FastXmlSerializer();
+ out.setOutput(fos, "utf-8");
+ writePendingOperationLocked(op, out);
+ out.endDocument();
+ mPendingFile.finishWrite(fos);
+ } catch (java.io.IOException e1) {
+ Log.w(TAG, "Error writing appending operation", e1);
+ mPendingFile.failWrite(fos);
+ } finally {
+ try {
+ fos.close();
+ } catch (IOException e) {}
+ }
+ }
+
static private byte[] flattenBundle(Bundle bundle) {
byte[] flatData = null;
Parcel parcel = Parcel.obtain();
@@ -2399,54 +2469,6 @@ public class SyncStorageEngine extends Handler {
return bundle;
}
- private static final String XML_ATTR_AUTHORITYID = "authority_id";
- private static final String XML_ATTR_SOURCE = "source";
- private static final String XML_ATTR_EXPEDITED = "expedited";
- private static final String XML_ATTR_REASON = "reason";
- /**
- * Write all currently pending ops to the pending ops file. TODO: Change this from xml
- * so that we can append to this file as before.
- */
- private void writePendingOperationsLocked() {
- final int N = mPendingOperations.size();
- FileOutputStream fos = null;
- try {
- if (N == 0) {
- if (DEBUG_FILE) Log.v(TAG, "Truncating " + mPendingFile.getBaseFile());
- mPendingFile.truncate();
- return;
- }
- if (DEBUG_FILE) Log.v(TAG, "Writing new " + mPendingFile.getBaseFile());
- fos = mPendingFile.startWrite();
- XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
- out.startDocument(null, true);
- out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
- out.startTag(null, "pending");
- out.attribute(null, "version", Integer.toString(PENDING_OPERATION_VERSION));
-
- for (int i = 0; i < N; i++) {
- PendingOperation pop = mPendingOperations.get(i);
- out.startTag(null, "op");
- out.attribute(null, XML_ATTR_AUTHORITYID, Integer.toString(pop.authorityId));
- out.attribute(null, XML_ATTR_SOURCE, Integer.toString(pop.syncSource));
- out.attribute(null, XML_ATTR_EXPEDITED, Boolean.toString(pop.expedited));
- out.attribute(null, XML_ATTR_REASON, Integer.toString(pop.reason));
- extrasToXml(out, pop.extras);
- out.endTag(null, "op");
- }
- out.endTag(null, "pending");
- out.endDocument();
- mPendingFile.finishWrite(fos);
- } catch (java.io.IOException e1) {
- Log.w(TAG, "Error writing pending operations", e1);
- if (fos != null) {
- mPendingFile.failWrite(fos);
- }
- }
- }
-
private void extrasToXml(XmlSerializer out, Bundle extras) throws java.io.IOException {
for (String key : extras.keySet()) {
out.startTag(null, "extra");
@@ -2479,35 +2501,6 @@ public class SyncStorageEngine extends Handler {
}
}
-// /**
-// * Update the pending ops file, if e
-// */
-// private void appendPendingOperationLocked(PendingOperation op) {
-// if (DEBUG_FILE) Log.v(TAG, "Appending to " + mPendingFile.getBaseFile());
-// FileOutputStream fos = null;
-// try {
-// fos = mPendingFile.openAppend();
-// } catch (java.io.IOException e) {
-// if (DEBUG_FILE) Log.v(TAG, "Failed append; writing full file");
-// writePendingOperationsLocked();
-// return;
-// }
-//
-// try {
-// Parcel out = Parcel.obtain();
-// writePendingOperationLocked(op, out);
-// fos.write(out.marshall());
-// out.recycle();
-// } catch (java.io.IOException e1) {
-// Log.w(TAG, "Error writing pending operations", e1);
-// } finally {
-// try {
-// fos.close();
-// } catch (java.io.IOException e2) {
-// }
-// }
-// }
-
private void requestSync(Account account, int userId, int reason, String authority,
Bundle extras) {
// If this is happening in the system process, then call the syncrequest listener
@@ -2568,7 +2561,9 @@ public class SyncStorageEngine extends Handler {
* Write all sync statistics to the sync status file.
*/
private void writeStatisticsLocked() {
- if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatisticsFile.getBaseFile());
+ if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+ Log.v(TAG, "Writing new " + mStatisticsFile.getBaseFile());
+ }
// The file is being written, so we don't need to have a scheduled
// write until the next change.
@@ -2611,7 +2606,7 @@ public class SyncStorageEngine extends Handler {
sb.append("Pending Ops: ").append(mPendingOperations.size()).append(" operation(s)\n");
for (PendingOperation pop : mPendingOperations) {
sb.append("(" + pop.account)
- .append(", " + pop.userId)
+ .append(", u" + pop.userId)
.append(", " + pop.authority)
.append(", " + pop.extras)
.append(")\n");
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index db030f1..c215f40 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -345,6 +345,12 @@ public final class WifiService extends IWifiManager.Stub {
return mBatchedScanSupported;
}
+ public void pollBatchedScan() {
+ enforceChangePermission();
+ if (mBatchedScanSupported == false) return;
+ mWifiStateMachine.requestBatchedScanPoll();
+ }
+
/**
* see {@link android.net.wifi.WifiManager#requestBatchedScan()}
*/
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
index dff6661..e44652f 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -67,7 +67,7 @@ public class SyncStorageEngineTest extends AndroidTestCase {
/**
* Test that we handle the case of a history row being old enough to purge before the
- * correcponding sync is finished. This can happen if the clock changes while we are syncing.
+ * corresponding sync is finished. This can happen if the clock changes while we are syncing.
*
*/
// TODO: this test causes AidlTest to fail. Omit for now
@@ -104,6 +104,17 @@ public class SyncStorageEngineTest extends AndroidTestCase {
engine.clearAndReadState();
assert(engine.getPendingOperationCount() == 1);
+ List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations();
+ SyncStorageEngine.PendingOperation popRetrieved = pops.get(0);
+ assertEquals(pop.account, popRetrieved.account);
+ assertEquals(pop.reason, popRetrieved.reason);
+ assertEquals(pop.userId, popRetrieved.userId);
+ assertEquals(pop.syncSource, popRetrieved.syncSource);
+ assertEquals(pop.authority, popRetrieved.authority);
+ assertEquals(pop.expedited, popRetrieved.expedited);
+ assertEquals(pop.serviceName, popRetrieved.serviceName);
+ assert(android.content.PeriodicSync.syncExtrasEquals(pop.extras, popRetrieved.extras));
+
}
/**