Fix intermittently failing unit test.

- This test fails if you haven't switched the phone screen on, which
  can be very confusing if you don't know about it.
- This cl introduces acquiring and releasing the screen wake lock to
  the integration test utils, and uses it to prevent this test failure.

Change-Id: I378b6effd56e912213eb0af81f8add5c3bba39f2
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index c1eefc0..fc3545b 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -27,6 +27,7 @@
 import com.android.contacts.tests.mocks.MockAccountTypeManager;
 import com.android.contacts.tests.mocks.MockContentProvider;
 import com.android.contacts.tests.mocks.MockContentProvider.Query;
+import com.android.contacts.util.IntegrationTestUtils;
 
 import android.content.ContentUris;
 import android.net.Uri;
@@ -65,6 +66,7 @@
     private ContactsMockContext mContext;
     private MockContentProvider mContactsProvider;
     private ContactDeletionInteraction mFragment;
+    private IntegrationTestUtils mUtils;
 
     public ContactDeletionInteractionTest() {
         super(FragmentTestActivity.class);
@@ -73,6 +75,10 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        // This test requires that the screen be turned on.
+        mUtils = new IntegrationTestUtils(getInstrumentation());
+        mUtils.acquireScreenWakeLock(getInstrumentation().getTargetContext());
+
         mContext = new ContactsMockContext(getInstrumentation().getTargetContext());
         InjectedServices services = new InjectedServices();
         services.setContentResolver(mContext.getContentResolver());
@@ -94,6 +100,7 @@
     @Override
     protected void tearDown() throws Exception {
         ContactsApplication.injectServices(null);
+        mUtils.releaseScreenWakeLock();
         super.tearDown();
     }
 
diff --git a/tests/src/com/android/contacts/util/IntegrationTestUtils.java b/tests/src/com/android/contacts/util/IntegrationTestUtils.java
index 9ce60a0..45dc981 100644
--- a/tests/src/com/android/contacts/util/IntegrationTestUtils.java
+++ b/tests/src/com/android/contacts/util/IntegrationTestUtils.java
@@ -16,8 +16,16 @@
 
 package com.android.contacts.util;
 
+import static android.os.PowerManager.ACQUIRE_CAUSES_WAKEUP;
+import static android.os.PowerManager.FULL_WAKE_LOCK;
+import static android.os.PowerManager.ON_AFTER_RELEASE;
+
+import com.google.common.base.Preconditions;
+
 import android.app.Activity;
 import android.app.Instrumentation;
+import android.content.Context;
+import android.os.PowerManager;
 import android.view.View;
 
 import junit.framework.Assert;
@@ -26,9 +34,17 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.FutureTask;
 
+import javax.annotation.concurrent.GuardedBy;
+import javax.annotation.concurrent.ThreadSafe;
+
 /** Some utility methods for making integration testing smoother. */
+@ThreadSafe
 public class IntegrationTestUtils {
+    private static final String TAG = "IntegrationTestUtils";
+
     private final Instrumentation mInstrumentation;
+    private final Object mLock = new Object();
+    @GuardedBy("mLock") private PowerManager.WakeLock mWakeLock;
 
     public IntegrationTestUtils(Instrumentation instrumentation) {
         mInstrumentation = instrumentation;
@@ -70,4 +86,36 @@
             throw e.getCause();
         }
     }
+
+    /**
+     * Wake up the screen, useful in tests that want or need the screen to be on.
+     * <p>
+     * This is usually called from setUp() for tests that require it.  After calling this method,
+     * {@link #releaseScreenWakeLock()} must be called, this is usually done from tearDown().
+     */
+    public void acquireScreenWakeLock(Context context) {
+        synchronized (mLock) {
+            Preconditions.checkState(mWakeLock == null, "mWakeLock was already held");
+            mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE))
+                    .newWakeLock(ACQUIRE_CAUSES_WAKEUP | ON_AFTER_RELEASE | FULL_WAKE_LOCK, TAG);
+            mWakeLock.acquire();
+        }
+    }
+
+    /** Release the wake lock previously acquired with {@link #acquireScreenWakeLock(Context)}. */
+    public void releaseScreenWakeLock() {
+        synchronized (mLock) {
+            // We don't use Preconditions to force you to have acquired before release.
+            // This is because we don't want unnecessary exceptions in tearDown() since they'll
+            // typically mask the actual exception that happened during the test.
+            // The other reason is that this method is most likely to be called from tearDown(),
+            // which is invoked within a finally block, so it's not infrequently the case that
+            // the setUp() method fails before getting the lock, at which point we don't want
+            // to fail in tearDown().
+            if (mWakeLock != null) {
+                mWakeLock.release();
+                mWakeLock = null;
+            }
+        }
+    }
 }