merge in oc-release history after reset to master
diff --git a/src/com/android/providers/calendar/CalendarAlarmManager.java b/src/com/android/providers/calendar/CalendarAlarmManager.java
index b107bf7..c77b654 100644
--- a/src/com/android/providers/calendar/CalendarAlarmManager.java
+++ b/src/com/android/providers/calendar/CalendarAlarmManager.java
@@ -30,7 +30,6 @@
 import android.net.Uri;
 import android.os.Build;
 import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
 import android.os.SystemClock;
 import android.provider.CalendarContract;
 import android.provider.CalendarContract.CalendarAlerts;
@@ -146,9 +145,10 @@
         mAlarmLock = new Object();
     }
 
-    private Intent getCheckNextAlarmIntent(boolean removeAlarms) {
+    @VisibleForTesting
+    static Intent getCheckNextAlarmIntent(Context context, boolean removeAlarms) {
         Intent intent = new Intent(CalendarAlarmManager.ACTION_CHECK_NEXT_ALARM);
-        intent.setClass(mContext, CalendarProviderBroadcastReceiver.class);
+        intent.setClass(context, CalendarProviderBroadcastReceiver.class);
         intent.putExtra(KEY_REMOVE_ALARMS, removeAlarms);
         return intent;
     }
@@ -171,7 +171,7 @@
             if (Log.isLoggable(CalendarProvider2.TAG, Log.DEBUG)) {
                 Log.d(CalendarProvider2.TAG, "Scheduling check of next Alarm");
             }
-            Intent intent = getCheckNextAlarmIntent(removeAlarms);
+            Intent intent = getCheckNextAlarmIntent(mContext, removeAlarms);
             PendingIntent pending = PendingIntent.getBroadcast(mContext, 0 /* ignored */, intent,
                     PendingIntent.FLAG_NO_CREATE);
             if (pending != null) {
@@ -197,7 +197,7 @@
      * @param triggerTimeMillis Time to run the next alarm check, in milliseconds.
      */
     void scheduleNextAlarmCheck(long triggerTimeMillis) {
-        Intent intent = getCheckNextAlarmIntent(false /* removeAlarms*/);
+        Intent intent = getCheckNextAlarmIntent(mContext, false /* removeAlarms*/);
         PendingIntent pending = PendingIntent.getBroadcast(
                 mContext, 0, intent, PendingIntent.FLAG_NO_CREATE);
         if (pending != null) {
@@ -229,8 +229,9 @@
      * @param cp2
      */
     void runScheduleNextAlarm(boolean removeAlarms, CalendarProvider2 cp2) {
-        SQLiteDatabase db = cp2.mDb;
+        SQLiteDatabase db = cp2.getWritableDatabase();
         if (db == null) {
+            Log.wtf(CalendarProvider2.TAG, "Unable to get the database.");
             return;
         }
 
diff --git a/src/com/android/providers/calendar/CalendarInstancesHelper.java b/src/com/android/providers/calendar/CalendarInstancesHelper.java
index 19b1faa..1ab5a01 100644
--- a/src/com/android/providers/calendar/CalendarInstancesHelper.java
+++ b/src/com/android/providers/calendar/CalendarInstancesHelper.java
@@ -58,9 +58,9 @@
     }
 
     private static final String TAG = "CalInstances";
-    private CalendarDatabaseHelper mDbHelper;
-    private MetaData mMetaData;
-    private CalendarCache mCalendarCache;
+    private final CalendarDatabaseHelper mDbHelper;
+    private final MetaData mMetaData;
+    private final CalendarCache mCalendarCache;
 
     private static final String SQL_WHERE_GET_EVENTS_ENTRIES =
             "((" + Events.DTSTART + " <= ? AND "
diff --git a/src/com/android/providers/calendar/CalendarProvider2.java b/src/com/android/providers/calendar/CalendarProvider2.java
index 08fe756..55e8c6d 100644
--- a/src/com/android/providers/calendar/CalendarProvider2.java
+++ b/src/com/android/providers/calendar/CalendarProvider2.java
@@ -39,8 +39,6 @@
 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;
 import android.os.SystemClock;
 import android.provider.BaseColumns;
@@ -444,8 +442,6 @@
     private Context mContext;
     private ContentResolver mContentResolver;
 
-    private static CalendarProvider2 mInstance;
-
     @VisibleForTesting
     protected CalendarAlarmManager mCalendarAlarm;
 
@@ -478,10 +474,6 @@
         return CalendarDatabaseHelper.getInstance(context);
     }
 
-    protected static CalendarProvider2 getInstance() {
-        return mInstance;
-    }
-
     @Override
     public void shutdown() {
         if (mDbHelper != null) {
@@ -506,8 +498,6 @@
     }
 
     private boolean initialize() {
-        mInstance = this;
-
         mContext = getContext();
         mContentResolver = mContext.getContentResolver();
 
diff --git a/src/com/android/providers/calendar/CalendarProviderBroadcastReceiver.java b/src/com/android/providers/calendar/CalendarProviderBroadcastReceiver.java
index 187f6e8..10c76c0 100644
--- a/src/com/android/providers/calendar/CalendarProviderBroadcastReceiver.java
+++ b/src/com/android/providers/calendar/CalendarProviderBroadcastReceiver.java
@@ -18,10 +18,13 @@
 
 import android.app.Activity;
 import android.content.BroadcastReceiver;
+import android.content.ContentProvider;
 import android.content.Context;
+import android.content.IContentProvider;
 import android.content.Intent;
 import android.provider.CalendarContract;
 import android.util.Log;
+import android.util.Slog;
 
 public class CalendarProviderBroadcastReceiver extends BroadcastReceiver {
     private static final String TAG = CalendarProvider2.TAG;
@@ -38,7 +41,16 @@
         if (Log.isLoggable(TAG, Log.DEBUG)) {
             Log.d(TAG, "Received intent: " + intent);
         }
-        final CalendarProvider2 provider = CalendarProvider2.getInstance();
+        final IContentProvider iprovider =
+                context.getContentResolver().acquireProvider(CalendarContract.AUTHORITY);
+        final ContentProvider cprovider = ContentProvider.coerceToLocalContentProvider(iprovider);
+
+        if (!(cprovider instanceof CalendarProvider2)) {
+            Slog.wtf(TAG, "CalendarProvider2 not found in CalendarProviderBroadcastReceiver.");
+            return;
+        }
+
+        final CalendarProvider2 provider = (CalendarProvider2) cprovider;
 
         final PendingResult result = goAsync();
 
@@ -53,6 +65,7 @@
                 Log.d(TAG, "Next alarm set.");
             }
 
+            result.setResultCode(Activity.RESULT_OK);
             result.finish();
         }).start();
 
diff --git a/src/com/android/providers/calendar/SQLiteContentProvider.java b/src/com/android/providers/calendar/SQLiteContentProvider.java
index 53fc7e7..0b18ff4 100644
--- a/src/com/android/providers/calendar/SQLiteContentProvider.java
+++ b/src/com/android/providers/calendar/SQLiteContentProvider.java
@@ -329,4 +329,12 @@
             mOriginalCallingUid.set(null);
         }
     }
+
+    SQLiteDatabase getReadableDatabase() {
+        return mOpenHelper != null ? mOpenHelper.getReadableDatabase() : null;
+    }
+
+    SQLiteDatabase getWritableDatabase() {
+        return mOpenHelper != null ? mOpenHelper.getWritableDatabase() : null;
+    }
 }
diff --git a/tests/src/com/android/providers/calendar/CalendarProviderBroadcastReceiverTest.java b/tests/src/com/android/providers/calendar/CalendarProviderBroadcastReceiverTest.java
new file mode 100644
index 0000000..09a19f5
--- /dev/null
+++ b/tests/src/com/android/providers/calendar/CalendarProviderBroadcastReceiverTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 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.providers.calendar;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@LargeTest
+public class CalendarProviderBroadcastReceiverTest extends AndroidTestCase {
+    /**
+     * Actually send the broadcast and make sure the provider won't crash.
+     */
+    public void testBroadcastToRealProvider() throws Exception {
+        final Intent intent = CalendarAlarmManager.getCheckNextAlarmIntent(getContext(),
+                /* removeAlarms=*/ false);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+
+        final AtomicInteger resultCodeReceiver = new AtomicInteger(Integer.MIN_VALUE);
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        getContext().sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                resultCodeReceiver.set(getResultCode());
+
+                latch.countDown();
+            }
+        }, null, 0, null, null);
+
+        assertTrue("Didn't receive the result.", latch.await(1, TimeUnit.MINUTES));
+        assertEquals(Activity.RESULT_OK, resultCodeReceiver.get());
+    }
+}