diff options
author | Paul Westbrook <pwestbro@google.com> | 2013-12-16 09:28:10 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-12-16 09:28:10 -0800 |
commit | c97e3dac6557f135e38d27574c07f5b2c112bd26 (patch) | |
tree | 772a4d782cd84912e90934e20ff7bf17ff2ccf75 | |
parent | 23509d11a86ab3eb05440de1e555805b425644e5 (diff) | |
parent | 34418a3f2c915bd83c3976198c1d51fac98a6d62 (diff) | |
download | android_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.xml | 10 | ||||
-rw-r--r-- | res/values/strings.xml | 12 | ||||
-rw-r--r-- | src/com/android/calendar/AllInOneActivity.java | 3 | ||||
-rw-r--r-- | src/com/android/calendar/GoogleCalendarUriIntentFilter.java | 112 | ||||
-rw-r--r-- | src/com/android/calendar/UpgradeReceiver.java | 29 | ||||
-rw-r--r-- | src/com/android/calendar/Utils.java | 23 |
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 |