Put some useful information in User-Agent Header
Put information in User-Agent:
* Build fingerprint
* Calendar or CalendarSyncAdapter package name + version code
* Package name of app making changes to provider for uphill syncs
Example:
google/mantaray/manta:K/MASTER/eng.aalbert.20121217.140040:eng/dev-keys:com.google.android.calendar:201212060:com.google.android.calendar Google-HTTP-Java-Client/1.11.0-beta (gzip)
Change-Id: I729c64ba9b922523d35903fcaf2a51cc234799a8
diff --git a/src/com/android/providers/calendar/CalendarDatabaseHelper.java b/src/com/android/providers/calendar/CalendarDatabaseHelper.java
index 7db2594..dc3deba 100644
--- a/src/com/android/providers/calendar/CalendarDatabaseHelper.java
+++ b/src/com/android/providers/calendar/CalendarDatabaseHelper.java
@@ -73,7 +73,7 @@
// 5xx for JB MR1
// 6xx for K
// Bump this to the next hundred at each major release.
- static final int DATABASE_VERSION = 502;
+ static final int DATABASE_VERSION = 600;
private static final int PRE_FROYO_SYNC_STATE_VERSION = 3;
@@ -522,6 +522,7 @@
CalendarContract.Events._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
CalendarContract.Events._SYNC_ID + " TEXT," +
CalendarContract.Events.DIRTY + " INTEGER," +
+ CalendarContract.Events.MUTATORS + " TEXT," +
CalendarContract.Events.LAST_SYNCED + " INTEGER DEFAULT 0," +
CalendarContract.Events.CALENDAR_ID + " INTEGER NOT NULL," +
CalendarContract.Events.TITLE + " TEXT," +
@@ -767,6 +768,7 @@
Calendars.ACCOUNT_TYPE + " TEXT," +
Calendars._SYNC_ID + " TEXT," +
Calendars.DIRTY + " INTEGER," +
+ Calendars.MUTATORS + " TEXT," +
Calendars.NAME + " TEXT," +
Calendars.CALENDAR_DISPLAY_NAME + " TEXT," +
Calendars.CALENDAR_COLOR + " INTEGER," +
@@ -1404,6 +1406,11 @@
createEventsView = true; // This is needed if the calendars or events schema changed
oldVersion = 502;
}
+ if (oldVersion < 600) {
+ upgradeToVersion600(db);
+ createEventsView = true; // This is needed if the calendars or events schema changed
+ oldVersion = 600;
+ }
if (createEventsView) {
createEventsView(db);
@@ -1480,6 +1487,15 @@
/* 6xx db version is for K release
/**********************************************************/
+ private void upgradeToVersion600(SQLiteDatabase db) {
+ /*
+ * Changes from version 5xx to 600:
+ * - add mutator columns to Events & calendars
+ */
+ db.execSQL("ALTER TABLE Events ADD COLUMN mutators TEXT;");
+ db.execSQL("ALTER TABLE Calendars ADD COLUMN mutators TEXT;");
+ }
+
/**********************************************************/
/* 5xx db version is for JB MR1 release
/**********************************************************/
@@ -3198,6 +3214,8 @@
+ " AS " + CalendarContract.Events._SYNC_ID + ","
+ Tables.EVENTS + "." + CalendarContract.Events.DIRTY
+ " AS " + CalendarContract.Events.DIRTY + ","
+ + Tables.EVENTS + "." + Events.MUTATORS
+ + " AS " + Events.MUTATORS + ","
+ CalendarContract.Events.LAST_SYNCED + ","
+ Tables.CALENDARS + "." + Calendars.ACCOUNT_NAME
+ " AS " + CalendarContract.Events.ACCOUNT_NAME + ","
diff --git a/src/com/android/providers/calendar/CalendarProvider2.java b/src/com/android/providers/calendar/CalendarProvider2.java
index d2027ee..35653e9 100644
--- a/src/com/android/providers/calendar/CalendarProvider2.java
+++ b/src/com/android/providers/calendar/CalendarProvider2.java
@@ -28,12 +28,14 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.UriMatcher;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
+import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
@@ -195,9 +197,14 @@
" WHERE " +
CalendarContract.EventsRawTimes.EVENT_ID + " = " + Tables.EVENTS + "." + Events._ID;
- private static final String SQL_UPDATE_EVENT_SET_DIRTY = "UPDATE " +
- Tables.EVENTS +
- " SET " + Events.DIRTY + "=1" +
+ private static final String SQL_UPDATE_EVENT_SET_DIRTY_AND_MUTATORS = "UPDATE " +
+ Tables.EVENTS + " SET " +
+ Events.DIRTY + "=1," +
+ Events.MUTATORS + "=? " +
+ " WHERE " + Events._ID + "=?";
+
+ private static final String SQL_QUERY_EVENT_MUTATORS = "SELECT " + Events.MUTATORS +
+ " FROM " + Tables.EVENTS +
" WHERE " + Events._ID + "=?";
private static final String SQL_WHERE_CALENDAR_COLOR = Calendars.ACCOUNT_NAME + "=? AND "
@@ -1712,6 +1719,7 @@
// If this isn't the sync adapter, set the "dirty" flag in any Event we modify.
if (!callerIsSyncAdapter) {
modValues.put(Events.DIRTY, true);
+ addMutator(modValues, Events.MUTATORS);
}
// Wrap all database accesses in a transaction.
@@ -2088,6 +2096,7 @@
case EVENTS:
if (!callerIsSyncAdapter) {
values.put(Events.DIRTY, 1);
+ addMutator(values, Events.MUTATORS);
}
if (!values.containsKey(Events.DTSTART)) {
if (values.containsKey(Events.ORIGINAL_SYNC_ID)
@@ -2561,7 +2570,31 @@
}
private void setEventDirty(long eventId) {
- mDb.execSQL(SQL_UPDATE_EVENT_SET_DIRTY, new Object[] {eventId});
+ final String mutators = DatabaseUtils.stringForQuery(
+ mDb,
+ SQL_QUERY_EVENT_MUTATORS,
+ new String[]{String.valueOf(eventId)});
+ final String packageName = getCallingPackageName();
+ final String newMutators;
+ if (TextUtils.isEmpty(mutators)) {
+ newMutators = packageName;
+ } else {
+ final String[] strings = mutators.split(",");
+ boolean found = false;
+ for (String string : strings) {
+ if (string.equals(packageName)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ newMutators = mutators + "," + packageName;
+ } else {
+ newMutators = mutators;
+ }
+ }
+ mDb.execSQL(SQL_UPDATE_EVENT_SET_DIRTY_AND_MUTATORS,
+ new Object[] {newMutators, eventId});
}
private long getOriginalId(String originalSyncId, String calendarId) {
@@ -3199,6 +3232,7 @@
ContentValues values = new ContentValues();
values.put(Events.DELETED, 1);
values.put(Events.DIRTY, 1);
+ addMutator(values, Events.MUTATORS);
mDb.update(Tables.EVENTS, values, SQL_WHERE_ID, selectionArgs);
// Exceptions that have been synced shouldn't be deleted -- the sync
@@ -3257,6 +3291,7 @@
ContentValues dirtyValues = new ContentValues();
dirtyValues.put(Events.DIRTY, "1");
+ addMutator(dirtyValues, Events.MUTATORS);
/*
* Re-issue the delete URI as a query. Note that, if this is a by-ID request, the ID
@@ -3340,6 +3375,7 @@
if (!callerIsSyncAdapter) {
ContentValues dirtyValues = new ContentValues();
dirtyValues.put(Events.DIRTY, "1");
+ addMutator(dirtyValues, Events.MUTATORS);
Iterator<Long> iter = eventIdSet.iterator();
while (iter.hasNext()) {
@@ -3448,6 +3484,7 @@
if (!callerIsSyncAdapter) {
dirtyValues = new ContentValues();
dirtyValues.put(Events.DIRTY, "1");
+ addMutator(dirtyValues, Events.MUTATORS);
}
final int idIndex = c.getColumnIndex(GENERIC_ID);
@@ -3774,6 +3811,7 @@
if (!callerIsSyncAdapter) {
modValues.put(Events.DIRTY, 1);
+ addMutator(modValues, Events.MUTATORS);
}
// Disallow updating the attendee status in the Events
@@ -3808,6 +3846,7 @@
} else {
if (modValues.containsKey(Events.DIRTY)
&& modValues.getAsInteger(Events.DIRTY) == 0) {
+ modValues.put(Events.MUTATORS, (String) null);
mDbHelper.removeDuplicateEvent(id);
}
}
@@ -3919,6 +3958,12 @@
}
if (!callerIsSyncAdapter) {
values.put(Calendars.DIRTY, 1);
+ addMutator(values, Calendars.MUTATORS);
+ } else {
+ if (values.containsKey(Calendars.DIRTY)
+ && values.getAsInteger(Calendars.DIRTY) == 0) {
+ values.put(Calendars.MUTATORS, (String) null);
+ }
}
Integer syncEvents = values.getAsInteger(Calendars.SYNC_EVENTS);
if (syncEvents != null) {
@@ -4624,6 +4669,7 @@
sCalendarsProjectionMap.put(Calendars.ACCOUNT_TYPE, Calendars.ACCOUNT_TYPE);
sCalendarsProjectionMap.put(Calendars._SYNC_ID, Calendars._SYNC_ID);
sCalendarsProjectionMap.put(Calendars.DIRTY, Calendars.DIRTY);
+ sCalendarsProjectionMap.put(Calendars.MUTATORS, Calendars.MUTATORS);
sCalendarsProjectionMap.put(Calendars.NAME, Calendars.NAME);
sCalendarsProjectionMap.put(
Calendars.CALENDAR_DISPLAY_NAME, Calendars.CALENDAR_DISPLAY_NAME);
@@ -4752,6 +4798,7 @@
sEventsProjectionMap.put(Calendars.CAL_SYNC9, Calendars.CAL_SYNC9);
sEventsProjectionMap.put(Calendars.CAL_SYNC10, Calendars.CAL_SYNC10);
sEventsProjectionMap.put(Events.DIRTY, Events.DIRTY);
+ sEventsProjectionMap.put(Events.MUTATORS, Events.MUTATORS);
sEventsProjectionMap.put(Events.LAST_SYNCED, Events.LAST_SYNCED);
sEventEntitiesProjectionMap = new HashMap<String, String>();
@@ -4807,6 +4854,7 @@
sEventEntitiesProjectionMap.put(Events.SYNC_DATA9, Events.SYNC_DATA9);
sEventEntitiesProjectionMap.put(Events.SYNC_DATA10, Events.SYNC_DATA10);
sEventEntitiesProjectionMap.put(Events.DIRTY, Events.DIRTY);
+ sEventEntitiesProjectionMap.put(Events.MUTATORS, Events.MUTATORS);
sEventEntitiesProjectionMap.put(Events.LAST_SYNCED, Events.LAST_SYNCED);
sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC1, Calendars.CAL_SYNC1);
sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC2, Calendars.CAL_SYNC2);
@@ -4992,4 +5040,28 @@
return newSelectionArgs;
}
}
+
+ private String getCallingPackageName() {
+ final PackageManager pm = getContext().getPackageManager();
+ final int uid = Binder.getCallingUid();
+ final String[] packages = pm.getPackagesForUid(uid);
+ if (packages != null && packages.length == 1) {
+ return packages[0];
+ }
+ final String name = pm.getNameForUid(uid);
+ if (name != null) {
+ return name;
+ }
+ return String.valueOf(uid);
+ }
+
+ private void addMutator(ContentValues values, String columnName) {
+ final String packageName = getCallingPackageName();
+ final String mutators = values.getAsString(columnName);
+ if (TextUtils.isEmpty(mutators)) {
+ values.put(columnName, packageName);
+ } else {
+ values.put(columnName, mutators + "," + packageName);
+ }
+ }
}