summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Westbrook <pwestbro@google.com>2013-12-16 09:28:10 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2013-12-16 09:28:10 -0800
commitc97e3dac6557f135e38d27574c07f5b2c112bd26 (patch)
tree772a4d782cd84912e90934e20ff7bf17ff2ccf75
parent23509d11a86ab3eb05440de1e555805b425644e5 (diff)
parent34418a3f2c915bd83c3976198c1d51fac98a6d62 (diff)
downloadandroid_packages_apps_Calendar-c97e3dac6557f135e38d27574c07f5b2c112bd26.tar.gz
android_packages_apps_Calendar-c97e3dac6557f135e38d27574c07f5b2c112bd26.tar.bz2
android_packages_apps_Calendar-c97e3dac6557f135e38d27574c07f5b2c112bd26.zip
am 34418a3f: Merge \'goog/ics-ub-calendar-fuchsia\' into klp-dev
* commit '34418a3f2c915bd83c3976198c1d51fac98a6d62': Allow app to upgrade database on install. Force a manual, incremental sync one time, as early as possible. Adding requiredAccountType attribute into fuchsia (DO NOT MERGE) Use the correct version code check for K. Use the holodark assets/ colors instead of hololight More calendar de-blueing Calendar deblueing Adding additional assets. Fix AOSP Calendar build New xxhdpi assets Abort onClick if no Window Focus Support PreferenceActivity.isValidFragment Use setExact on K and up only. Remove negative margin fron all day label Call build() on the Builder, not the Style. Process RSVP Intent Without Event Editor
-rw-r--r--AndroidManifest.xml10
-rw-r--r--res/values/strings.xml12
-rw-r--r--src/com/android/calendar/AllInOneActivity.java3
-rw-r--r--src/com/android/calendar/GoogleCalendarUriIntentFilter.java112
-rw-r--r--src/com/android/calendar/UpgradeReceiver.java29
-rw-r--r--src/com/android/calendar/Utils.java23
6 files changed, 154 insertions, 35 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9c05c8dd..8f763f09 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -189,6 +189,16 @@
<receiver android:name=".alerts.GlobalDismissManager"
android:exported="false" />
+ <receiver android:name=".UpgradeReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
+ </intent-filter>
+ </receiver>
+
<service android:name=".alerts.AlertService" />
<service android:name=".alerts.DismissAlarmsService" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 49bcf874..caec61b5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -208,6 +208,18 @@
<string name="creating_event_with_guest">"Invitations will be sent."</string>
<!-- Toast message displayed when an existing event with guests is saved after being modified -->
<string name="saving_event_with_guest">"Updates will be sent."</string>
+
+ <!-- Toast message displayed responding to an event from an email as accepted
+ [CHAR LIMIT=50] -->
+ <string name="rsvp_accepted">"Responded yes."</string>
+ <!-- Toast message displayed responding to an event from an email as tentative
+ [CHAR LIMIT=50] -->
+ <string name="rsvp_tentative">"Responded maybe."</string>
+ <!-- Toast message displayed responding to an event from an email as declined
+ [CHAR LIMIT=50] -->
+ <string name="rsvp_declined">"Responded no."</string>
+
+
<!-- Title of message displayed to indicate available calendars are being loaded when creating
a new event -->
diff --git a/src/com/android/calendar/AllInOneActivity.java b/src/com/android/calendar/AllInOneActivity.java
index e61d69c8..0e1feb49 100644
--- a/src/com/android/calendar/AllInOneActivity.java
+++ b/src/com/android/calendar/AllInOneActivity.java
@@ -507,6 +507,9 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH
protected void onResume() {
super.onResume();
+ // Check if the upgrade code has ever been run. If not, force a sync just this one time.
+ Utils.trySyncAndDisableUpgradeReceiver(this);
+
// Must register as the first activity because this activity can modify
// the list of event handlers in it's handle method. This affects who
// the rest of the handlers the controller dispatches to are.
diff --git a/src/com/android/calendar/GoogleCalendarUriIntentFilter.java b/src/com/android/calendar/GoogleCalendarUriIntentFilter.java
index 4a3c0cbd..fef89e8e 100644
--- a/src/com/android/calendar/GoogleCalendarUriIntentFilter.java
+++ b/src/com/android/calendar/GoogleCalendarUriIntentFilter.java
@@ -17,26 +17,24 @@
package com.android.calendar;
-import static android.provider.CalendarContract.Attendees.ATTENDEE_STATUS;
-import static android.provider.CalendarContract.Attendees.ATTENDEE_STATUS_ACCEPTED;
-import static android.provider.CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED;
-import static android.provider.CalendarContract.Attendees.ATTENDEE_STATUS_NONE;
-import static android.provider.CalendarContract.Attendees.ATTENDEE_STATUS_TENTATIVE;
-import static android.provider.CalendarContract.EXTRA_EVENT_BEGIN_TIME;
-import static android.provider.CalendarContract.EXTRA_EVENT_END_TIME;
-
import android.app.Activity;
import android.content.ActivityNotFoundException;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
import android.content.ContentUris;
+import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
+import android.provider.CalendarContract;
+import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Events;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
+import android.widget.Toast;
import com.android.calendarcommon2.DateException;
import com.android.calendarcommon2.Duration;
@@ -144,11 +142,14 @@ public class GoogleCalendarUriIntentFilter extends Activity {
Uri uri = intent.getData();
if (uri != null) {
String[] eidParts = extractEidAndEmail(uri);
- if (debug) Log.d(TAG, "eidParts=" + eidParts );
-
- if (eidParts != null) {
- final String selection = Events._SYNC_ID + " LIKE \"%" + eidParts[0]
- + "\" AND " + Calendars.OWNER_ACCOUNT + " LIKE \"" + eidParts[1] + "\"";
+ if (eidParts == null) {
+ Log.i(TAG, "Could not find event for uri: " +uri);
+ } else {
+ final String syncId = eidParts[0];
+ final String ownerAccount = eidParts[1];
+ if (debug) Log.d(TAG, "eidParts=" + syncId + "/" + ownerAccount);
+ final String selection = Events._SYNC_ID + " LIKE \"%" + syncId + "\" AND "
+ + Calendars.OWNER_ACCOUNT + " LIKE \"" + ownerAccount + "\"";
if (debug) Log.d(TAG, "selection: " + selection);
Cursor eventCursor = getContentResolver().query(Events.CONTENT_URI,
@@ -156,13 +157,15 @@ public class GoogleCalendarUriIntentFilter extends Activity {
Calendars.CALENDAR_ACCESS_LEVEL + " desc");
if (debug) Log.d(TAG, "Found: " + eventCursor.getCount());
- if (eventCursor != null && eventCursor.getCount() > 0) {
- if (eventCursor.getCount() > 1) {
- Log.i(TAG, "NOTE: found " + eventCursor.getCount()
- + " matches on event with id='" + eidParts[0] + "'");
- // Don't print eidPart[1] as it contains the user's PII
- }
+ if (eventCursor == null || eventCursor.getCount() == 0) {
+ Log.i(TAG, "NOTE: found no matches on event with id='" + syncId + "'");
+ return;
+ }
+ Log.i(TAG, "NOTE: found " + eventCursor.getCount()
+ + " matches on event with id='" + syncId + "'");
+ // Don't print eidPart[1] as it contains the user's PII
+ try {
// Get info from Cursor
while (eventCursor.moveToNext()) {
int eventId = eventCursor.getInt(EVENT_INDEX_ID);
@@ -194,22 +197,19 @@ public class GoogleCalendarUriIntentFilter extends Activity {
}
}
- eventCursor.close();
- eventCursor = null;
-
// Pick up attendee status action from uri clicked
- int attendeeStatus = ATTENDEE_STATUS_NONE;
+ int attendeeStatus = Attendees.ATTENDEE_STATUS_NONE;
if ("RESPOND".equals(uri.getQueryParameter("action"))) {
try {
switch (Integer.parseInt(uri.getQueryParameter("rst"))) {
case 1: // Yes
- attendeeStatus = ATTENDEE_STATUS_ACCEPTED;
+ attendeeStatus = Attendees.ATTENDEE_STATUS_ACCEPTED;
break;
case 2: // No
- attendeeStatus = ATTENDEE_STATUS_DECLINED;
+ attendeeStatus = Attendees.ATTENDEE_STATUS_DECLINED;
break;
case 3: // Maybe
- attendeeStatus = ATTENDEE_STATUS_TENTATIVE;
+ attendeeStatus = Attendees.ATTENDEE_STATUS_TENTATIVE;
break;
}
} catch (NumberFormatException e) {
@@ -218,22 +218,24 @@ public class GoogleCalendarUriIntentFilter extends Activity {
}
}
- // Send intent to calendar app
- Uri calendarUri = ContentUris.withAppendedId(Events.CONTENT_URI,
- eventId);
+ final Uri calendarUri = ContentUris.withAppendedId(
+ Events.CONTENT_URI, eventId);
intent = new Intent(Intent.ACTION_VIEW, calendarUri);
intent.setClass(this, EventInfoActivity.class);
- intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
- intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
- if (attendeeStatus != ATTENDEE_STATUS_NONE) {
- intent.putExtra(ATTENDEE_STATUS, attendeeStatus);
+ intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis);
+ intent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis);
+ if (attendeeStatus == Attendees.ATTENDEE_STATUS_NONE) {
+ startActivity(intent);
+ } else {
+ updateSelfAttendeeStatus(
+ eventId, ownerAccount, attendeeStatus, intent);
}
- startActivity(intent);
finish();
return;
}
+ } finally {
+ eventCursor.close();
}
- if (eventCursor != null) eventCursor.close();
}
}
@@ -246,4 +248,44 @@ public class GoogleCalendarUriIntentFilter extends Activity {
}
finish();
}
+
+ private void updateSelfAttendeeStatus(
+ int eventId, String ownerAccount, final int status, final Intent intent) {
+ final ContentResolver cr = getContentResolver();
+ final AsyncQueryHandler queryHandler =
+ new AsyncQueryHandler(cr) {
+ @Override
+ protected void onUpdateComplete(int token, Object cookie, int result) {
+ if (result == 0) {
+ Log.w(TAG, "No rows updated - starting event viewer");
+ intent.putExtra(Attendees.ATTENDEE_STATUS, status);
+ startActivity(intent);
+ return;
+ }
+ final int toastId;
+ switch (status) {
+ case Attendees.ATTENDEE_STATUS_ACCEPTED:
+ toastId = R.string.rsvp_accepted;
+ break;
+ case Attendees.ATTENDEE_STATUS_DECLINED:
+ toastId = R.string.rsvp_declined;
+ break;
+ case Attendees.ATTENDEE_STATUS_TENTATIVE:
+ toastId = R.string.rsvp_tentative;
+ break;
+ default:
+ return;
+ }
+ Toast.makeText(GoogleCalendarUriIntentFilter.this,
+ toastId, Toast.LENGTH_LONG).show();
+ }
+ };
+ final ContentValues values = new ContentValues();
+ values.put(Attendees.ATTENDEE_STATUS, status);
+ queryHandler.startUpdate(0, null,
+ Attendees.CONTENT_URI,
+ values,
+ Attendees.ATTENDEE_EMAIL + "=? AND " + Attendees.EVENT_ID + "=?",
+ new String[]{ ownerAccount, String.valueOf(eventId) });
+ }
}
diff --git a/src/com/android/calendar/UpgradeReceiver.java b/src/com/android/calendar/UpgradeReceiver.java
new file mode 100644
index 00000000..0e89286d
--- /dev/null
+++ b/src/com/android/calendar/UpgradeReceiver.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.calendar;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class UpgradeReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ Utils.trySyncAndDisableUpgradeReceiver(context);
+ }
+
+} \ No newline at end of file
diff --git a/src/com/android/calendar/Utils.java b/src/com/android/calendar/Utils.java
index 4018f22b..41961852 100644
--- a/src/com/android/calendar/Utils.java
+++ b/src/com/android/calendar/Utils.java
@@ -22,6 +22,7 @@ import android.accounts.Account;
import android.app.Activity;
import android.app.SearchManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -848,6 +849,28 @@ public class Utils {
return (0xff000000) | ((r | g | b) >> 8);
}
+ public static void trySyncAndDisableUpgradeReceiver(Context context) {
+ final PackageManager pm = context.getPackageManager();
+ ComponentName upgradeComponent = new ComponentName(context, UpgradeReceiver.class);
+ if (pm.getComponentEnabledSetting(upgradeComponent) ==
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+ // The upgrade receiver has been disabled, which means this code has been run before,
+ // so no need to sync.
+ return;
+ }
+
+ Bundle extras = new Bundle();
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+ ContentResolver.requestSync(
+ null /* no account */,
+ Calendars.CONTENT_URI.getAuthority(),
+ extras);
+
+ // Now unregister the receiver so that we won't continue to sync every time.
+ pm.setComponentEnabledSetting(upgradeComponent,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
+ }
+
// A single strand represents one color of events. Events are divided up by
// color to make them convenient to draw. The black strand is special in
// that it holds conflicting events as well as color settings for allday on