Sample app and test package for a Service

Change-Id: I6589a1b761f5c40b86f1319c30ead2409113b647
diff --git a/samples/Alarm/AndroidManifest.xml b/samples/Alarm/AndroidManifest.xml
new file mode 100644
index 0000000..6a7a831
--- /dev/null
+++ b/samples/Alarm/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!--
+    Declares the contents of this Android application. The xmlns:android
+    attribute brings in the Android platform namespace, and the
+    "package" attribute provides a unique name for the application.
+    If you use this file as a template in your own application, you must change
+    the package name from "com.example.android" to one that you own or have
+    control over.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.newalarm"
+    android:versionCode="2"
+    android:versionName="2.0">
+    <!--
+        Declares the application, its icon, and its visible label
+     -->
+    <application
+        android:icon="@drawable/icon"
+        android:label="@string/app_name">
+        <!--
+            Declares the activity's class name and visible label. The leading "." indicates
+            that the name should be preceded by the application's Android package name.
+         -->
+        <activity
+            android:name=".AlarmActivity"
+            android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <service
+            android:name=".AlarmService"
+            android:label="@string/alarm_service"
+            android:process="com.example.android.newalarm">
+        </service>
+    </application>
+    <uses-sdk android:targetSdkVersion="4" android:minSdkVersion="3"/>
+</manifest>
diff --git a/samples/Alarm/_index.html b/samples/Alarm/_index.html
new file mode 100644
index 0000000..dff51ce
--- /dev/null
+++ b/samples/Alarm/_index.html
@@ -0,0 +1,29 @@
+<p>
+    This sample is a revised version of the AlarmService functionality included in the
+    ApiDemos sample application. It is used as the application under test
+    for the <a href="../AlarmServiceTest/index.html">Alarm Service Test</a>
+    sample test application.
+</p>
+<p>
+    This application demonstrates a simple Android service that is started when needed by
+    <code>Context.startService(Intent)</code> and stops itself when its work is done. You can
+    use this type of service to move long-running or periodic tasks into the background. For
+    example, you could use this type of service to perform data synchronization.
+</p>
+<p>
+    In the sample, the service simply runs for 15 seconds and then stops itself. The wait is
+    implemented in a separate thread that uses a thread-safe object. This illustrates how to
+    set up a service that runs multiple threads that depend on one or more objects that must be
+    made thread-safe.
+</p>
+<p>
+    The application also contains the <code>AlarmActivity</code> activity that is a client of the
+    service. You use the activity to control when the service starts and stops. By default, the
+    activity fires off the service every thirty seconds. In effect, the service starts after
+    thirty seconds, runs for 15 seconds, stops, and then runs again automatically in another
+    15 seconds. You also use the client to stop this cycle.
+</p>
+<p>
+    The test application <a href="tests/index.html">AlarmServiceTest</a>
+    shows you how to set up a test of this service.
+</p>
diff --git a/samples/Alarm/res/drawable/icon.png b/samples/Alarm/res/drawable/icon.png
new file mode 100644
index 0000000..5ae7701
--- /dev/null
+++ b/samples/Alarm/res/drawable/icon.png
Binary files differ
diff --git a/samples/Alarm/res/drawable/stat_sample.png b/samples/Alarm/res/drawable/stat_sample.png
new file mode 100755
index 0000000..6c9ba0a
--- /dev/null
+++ b/samples/Alarm/res/drawable/stat_sample.png
Binary files differ
diff --git a/samples/Alarm/res/layout/main.xml b/samples/Alarm/res/layout/main.xml
new file mode 100644
index 0000000..3d79e2b
--- /dev/null
+++ b/samples/Alarm/res/layout/main.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/alarm_service"/>
+    <Button android:id="@+id/start_alarm"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/start_alarm_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/stop_alarm"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/stop_alarm_service" />
+</LinearLayout>
+
diff --git a/samples/Alarm/res/values/strings.xml b/samples/Alarm/res/values/strings.xml
new file mode 100644
index 0000000..18a34cc
--- /dev/null
+++ b/samples/Alarm/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+    <string name="app_name">Alarm</string>
+    <string name="alarm_service">
+        This shows how to schedule a repeating alarm that starts a service.</string>
+    <string name="start_alarm_service">Start Alarm Service</string>
+    <string name="stop_alarm_service">Stop Alarm Service</string>
+    <string name="repeating_started">
+        Repeating timer started. Starts AlarmService every 30 seconds.</string>
+    <string name="alarm_service_started">The sample service is running.</string>
+    <string name="alarm_service_label">Sample Alarm Service</string>
+    <string name="alarm_service_finished">The sample service is no longer running.</string>
+    <string name="repeating_stopped">
+        Repeating timer stopped. AlarmService will no longer be started.</string>
+</resources>
diff --git a/samples/Alarm/src/com/example/android/newalarm/AlarmActivity.java b/samples/Alarm/src/com/example/android/newalarm/AlarmActivity.java
new file mode 100644
index 0000000..d26507d
--- /dev/null
+++ b/samples/Alarm/src/com/example/android/newalarm/AlarmActivity.java
@@ -0,0 +1,133 @@
+/*
+ * 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.example.android.newalarm;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.SystemClock;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+/**
+ * This is the activity that controls AlarmService.
+ * <p>
+ * When the user clicks the "Start Alarm Service" button, it triggers a repeating countdown
+ * timer. Every thirty seconds, the timer starts AlarmService, which then runs for 15 seconds
+ * and shuts itself down.
+ * </p>
+ * <p>
+ * When the user clicks the "Stop Alarm Service" button, it stops the countdown timer.
+ * </p>
+ */
+
+public class AlarmActivity extends Activity {
+    // 30 seconds in milliseconds
+    private static final long THIRTY_SECONDS_MILLIS = 30 * 1000;
+
+    // An intent for AlarmService, to trigger it as if the Activity called startService().
+    private PendingIntent mAlarmSender;
+
+    // Contains a handle to the system alarm service
+    private AlarmManager mAlarmManager;
+
+    /**
+     * This method is called when Android starts the activity. It initializes the UI.
+     * <p>
+     * This method is automatically called when Android starts the Activity
+     * </p>
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create a PendingIntent to trigger a startService() for AlarmService
+        mAlarmSender = PendingIntent.getService(  // set up an intent for a call to a service
+            AlarmActivity.this,  // the current context
+            0,  // request code (not used)
+            new Intent(AlarmActivity.this, AlarmService.class),  // A new Service intent
+            0   // flags (none are required for a service)
+        );
+
+        // Creates the main view
+        setContentView(R.layout.main);
+
+        // Finds the button that starts the repeating countdown timer
+        Button button = (Button)findViewById(R.id.start_alarm);
+
+        // Sets the listener for the start button
+        button.setOnClickListener(mStartAlarmListener);
+
+        // Finds the button that stops countdown timer
+        button = (Button)findViewById(R.id.stop_alarm);
+
+        // Sets the listener for the stop button
+        button.setOnClickListener(mStopAlarmListener);
+
+        // Gets the handle to the system alarm service
+        mAlarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
+    }
+
+    // Creates a new anonymous click listener for the start button. It starts the repeating
+    //  countdown timer.
+    private OnClickListener mStartAlarmListener = new OnClickListener() {
+        // Sets the callback for when the button is clicked
+        public void onClick(View v) {
+
+            // Sets the time when the alarm will first go off
+            // The Android AlarmManager uses this form of the current time.
+            long firstAlarmTime = SystemClock.elapsedRealtime();
+
+            // Sets a repeating countdown timer that triggers AlarmService
+            mAlarmManager.setRepeating(
+                AlarmManager.ELAPSED_REALTIME_WAKEUP, // based on time since last wake up
+                firstAlarmTime,  // sends the first alarm immediately
+                THIRTY_SECONDS_MILLIS,  // repeats every thirty seconds
+                mAlarmSender  // when the alarm goes off, sends this Intent
+            );
+
+            // Notifies the user that the repeating countdown timer has been started
+            Toast.makeText(
+                AlarmActivity.this,  //  the current context
+                R.string.repeating_started,  // the message to display
+                Toast.LENGTH_LONG  // how long to display the message
+            ).show();  // show the message on the screen
+        }
+    };
+
+    // Creates a new anonymous click listener for the stop button. It shuts off the repeating
+    // countdown timer.
+    private OnClickListener mStopAlarmListener = new OnClickListener() {
+        // Sets the callback for when the button is clicked
+        public void onClick(View v) {
+
+            // Cancels the repeating countdown timer
+            mAlarmManager.cancel(mAlarmSender);
+
+            // Notifies the user that the repeating countdown timer has been stopped
+            Toast.makeText(
+                AlarmActivity.this,  //  the current context
+                R.string.repeating_stopped,  // the message to display
+                Toast.LENGTH_LONG  // how long to display the message
+            ).show(); // display the message
+        }
+    };
+}
diff --git a/samples/Alarm/src/com/example/android/newalarm/AlarmService.java b/samples/Alarm/src/com/example/android/newalarm/AlarmService.java
new file mode 100644
index 0000000..1f88206
--- /dev/null
+++ b/samples/Alarm/src/com/example/android/newalarm/AlarmService.java
@@ -0,0 +1,216 @@
+/*
+ * 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.example.android.newalarm;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.widget.Toast;
+
+/**
+ * <p>
+ * This class implements a service. The service is started by AlarmActivity, which contains a
+ * repeating countdown timer that sends a PendingIntent. The user starts and stops the timer with
+ * buttons in the UI.
+ * </p>
+ * <p>
+ * When this service is started, it creates a Runnable and starts it in a new Thread. The
+ * Runnable does a synchronized lock on the service's Binder object for 15 seconds, then issues
+ * a stopSelf(). The net effect is a new worker thread that takes 15 seconds to run and then
+ * shuts down the entire service. The activity restarts the service after 15 more seconds, when the
+ * countdown timer triggers again.
+ * </p>
+ * <p>
+ * This service is provided as the service under test for the sample test application
+ * AlarmServiceTest.
+ * </p>
+ * <p>
+ * Note: Since this sample is based on the Android 1.5 platform, it does not implement
+ * onStartCommand. See the Javadoc for android.app.Service for more details.
+ * </p>
+ */
+public class AlarmService extends Service {
+    // Defines a label for the thread that this service starts
+    private static final String ALARM_SERVICE_THREAD = "AlarmService";
+
+    // Defines 15 seconds
+    public static final long WAIT_TIME_SECONDS = 15;
+
+    // Define the number of milliseconds in one second
+    public static final long MILLISECS_PER_SEC = 1000;
+
+    /*
+     * For testing purposes, the following variables are defined as fields and set to
+     * package visibility.
+     */
+
+    // The NotificationManager used to send notifications to the status bar.
+    NotificationManager mNotificationManager;
+
+    // An Intent that displays the client if the user clicks the notification.
+    PendingIntent mContentIntent;
+
+    // A Notification to send to the Notification Manager when the service is started.
+    Notification mNotification;
+
+    // A Binder, used as the lock object for the worker thread.
+    IBinder mBinder = new AlarmBinder();
+
+    // A Thread object that will run the background task
+    Thread mWorkThread;
+
+    // The Runnable that is the service's "task". This illustrates how a service is used to
+    // offload work from a client.
+    Runnable mWorkTask = new Runnable() {
+        public void run() {
+            // Sets the wait time to 15 seconds, simulating a 15-second background task.
+            long waitTime = System.currentTimeMillis() + WAIT_TIME_SECONDS * MILLISECS_PER_SEC;
+
+            // Puts the wait in a while loop to ensure that it actually waited 15 seconds.
+            // This covers the situation where an interrupt might have overridden the wait.
+            while (System.currentTimeMillis() < waitTime) {
+                // Waits for 15 seconds or interruption
+                synchronized (mBinder) {
+                    try {
+                        // Waits for 15 seconds or until an interrupt triggers an exception.
+                        // If an interrupt occurs, the wait is recalculated to ensure a net
+                        // wait of 15 seconds.
+                        mBinder.wait(waitTime - System.currentTimeMillis());
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+            // Stops the current service. In response, Android calls onDestroy().
+            stopSelf();
+        }
+    };
+
+    /**
+     *  Makes a full concrete subclass of Binder, rather than doing it in line, for readability.
+     */
+    public class AlarmBinder extends Binder {
+        // Constructor. Calls the super constructor to set up the instance.
+        public AlarmBinder() {
+            super();
+        }
+
+        @Override
+        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+            throws RemoteException {
+
+            // Call the parent method with the arguments passed in
+            return super.onTransact(code, data, reply, flags);
+        }
+    }
+
+    /**
+     * Initializes the service when it is first started by a call to startService() or
+     * bindService().
+     */
+    @Override
+    public void onCreate() {
+        // Gets a handle to the system mNotification service.
+        mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+
+        // Updates the status bar to indicate that this service is running.
+        showNotification();
+
+        // Creates a new thread. A new thread is used so that the service's work doesn't block
+        // anything on the calling client's thread. By default, a service runs in the same
+        // process and thread as the client that starts it.
+        mWorkThread = new Thread(
+            null,  // threadgroup (in this case, null)
+            mWorkTask, // the Runnable that will run in this thread
+            ALARM_SERVICE_THREAD
+        );
+        // Starts the thread
+        mWorkThread.start();
+    }
+
+    /**
+     * Stops the service in response to the stopSelf() issued when the wait is over. Other
+     * clients that use this service could stop it by issuing a stopService() or a stopSelf() on
+     * the service object.
+     */
+    @Override
+    public void onDestroy() {
+        // Cancels the status bar mNotification based on its ID, which is set in showNotification().
+        mNotificationManager.cancel(R.string.alarm_service_started);
+
+        // Sends a notification to the screen.
+        Toast.makeText(
+            this,  // the current context
+            R.string.alarm_service_finished,  // the message to show
+            Toast.LENGTH_LONG   // how long to keep the message on the screen
+        ).show();  // show the text
+    }
+
+    // Returns the service's binder object to clients that issue onBind().
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    /**
+     * Displays a notification in the status bar that this service is running. This method
+     * also creates an Intent for the AlarmActivity client and attaches it to the notification
+     * line. If the user clicks the line in the expanded status window, the Intent triggers
+     * AlarmActivity.
+     */
+    private void showNotification() {
+        // Sets the text to use for the status bar and status list views.
+        CharSequence notificationText = getText(R.string.alarm_service_started);
+
+        // Sets the icon, status bar text, and display time for the mNotification.
+        mNotification = new Notification(
+            R.drawable.stat_sample,  // the status icon
+            notificationText, // the status text
+            System.currentTimeMillis()  // the time stamp
+        );
+
+        // Sets up the Intent that starts AlarmActivity
+        mContentIntent = PendingIntent.getActivity(
+            this,  // Start the Activity in the current context
+            0,   // not used
+            new Intent(this, AlarmActivity.class),  // A new Intent for AlarmActivity
+            0  // Use an existing activity instance if available
+        );
+
+        // Creates a new content view for the mNotification. The view appears when the user
+        // shows the expanded status window.
+        mNotification.setLatestEventInfo(
+            this,  //  Put the content view in the current context
+            getText(R.string.alarm_service_label),  // The text to use as the label of the entry
+            notificationText,  // The text to use as the contents of the entry
+            mContentIntent  // The intent to send when the entry is clicked
+        );
+
+        // Sets a unique ID for the notification and sends it to NotificationManager to be
+        // displayed. The ID is the integer marker for the notification string, which is
+        // guaranteed to be unique within the entire application.
+        mNotificationManager.notify(
+            R.string.alarm_service_started,  // unique id for the mNotification
+            mNotification   // the mNotification object
+        );
+    }
+}
diff --git a/samples/Alarm/tests/AndroidManifest.xml b/samples/Alarm/tests/AndroidManifest.xml
new file mode 100644
index 0000000..8688920
--- /dev/null
+++ b/samples/Alarm/tests/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!--
+    Declare the contents of this Android test package. The xmlns:android
+    attribute brings in the Android platform namespace, and the
+    "package" attribute provides a unique name for the package.
+    If you use this file as a template in your own test package, you must change
+    the package name from "com.example.android" to one that you own or have
+    control over.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.newalarm.test"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <!--
+        Must use the application element to include the uses-library element.
+     -->
+    <application>
+        <!--
+            Tells Android to include this library in the test package's class loader.
+            The test runner is not included by default in a manifest file.
+        -->
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <!--
+        Specifies that the test package requires API platform level 3 (Android 1.5) or above.
+        The installer will not install this package onto a device or emulator that is running an
+        older platform version.
+     -->
+    <uses-sdk android:minSdkVersion="3" />
+    <!--
+        Declares the instrumentation for this application. The instrumentation class is
+        specified by the "name" attribute, and must name a subclass of
+        android.app.Instrumentation. The application that is run by the instrumentation object is
+        specified by the "targetPackage" attribute.
+     -->
+    <instrumentation
+        android:targetPackage="com.example.android.newalarm"
+        android:name="android.test.InstrumentationTestRunner" />
+</manifest>
diff --git a/samples/Alarm/tests/_index.html b/samples/Alarm/tests/_index.html
new file mode 100644
index 0000000..614125d
--- /dev/null
+++ b/samples/Alarm/tests/_index.html
@@ -0,0 +1,50 @@
+<p>
+    This sample is the test application for the <a href="../Alarm/index.html">Alarm</a>
+    sample application. It tests the application's <code>AlarmService</code> service.
+</p>
+<p>
+    The test application uses the
+    <a href="../../../reference/android/test/ServiceTestCase.html">
+    <code>ServiceTestCase</code></a>  test case class,
+    which extends the JUnit <a href="../../../reference/junit/framework/TestCase.html">
+    <code>TestCase</code></a> class. The test runner is
+    <a href="../../../reference/android/test/InstrumentationTestRunner.html">
+    <code>InstrumentationTestRunner</code></a>.
+</p>
+<p>
+    The application shows how to set up a test application project,
+    how to create the <a href="AndroidManifest.html"><code>AndroidManifest.xml</code></a>
+    file for a test application, and how to set up a test case class for a service. The
+    test case class, <a href="src/com/android/example/newalarm/ServiceAlarmTest.html">
+    <code>AlarmServiceTest</code></a>, contains tests that demonstrate the following
+    Android test patterns:
+</p>
+    <ul>
+        <li>
+            Test setup: The <code>setUp()</code> method re-initializes the state of the
+            service under test before each test is run.
+        </li>
+        <li>
+            Service start: The <code>Service.testServiceCreate()</code> test confirms that the
+            service starts correctly and initializes the variables it needs to provide its
+            services.
+        </li>
+    </ul>
+<p>
+    The <a href="AndroidManifest.html">manifest</a> declares an <code>&lt;instrumentation&gt;</code>
+    element that links the test application with the application under test. Specifically, the
+    element's <code>android:name</code> attribute specifies <code>InstrumentationTestRunner</code>
+    as the instrumentation to use. The <code>android:targetPackage</code> attribute specifies
+    <code>com.android.example.newalarm</code> as the name of the Android package that contains the
+    service under test.
+</p>
+<p class="note">
+    <strong>Note:</strong> <code>AlarmServiceTest.java</code> uses the Java package name
+    <code>com.example.android.newalarm</code>, which is the same package used by service under
+    test, <code>AlarmService.java</code>. This allows the test class to access members in the
+    service under test that are defined with package visibility. To prevent conflicts, though,
+    the generated java file <code>R.java</code> for <code>AlarmServiceTest</code> uses the
+    Java package name <code>com.example.android.newalarm.test</code>. For the same reason, the
+    Android package name for the test application (specified in the manifest file), is
+    <code>com.example.android.newalarm.test</code>.
+</p>
diff --git a/samples/Alarm/tests/src/com/example/android/newalarm/AlarmServiceTest.java b/samples/Alarm/tests/src/com/example/android/newalarm/AlarmServiceTest.java
new file mode 100644
index 0000000..4d6c7ad
--- /dev/null
+++ b/samples/Alarm/tests/src/com/example/android/newalarm/AlarmServiceTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.example.android.newalarm;
+
+import android.content.Intent;
+import android.test.ServiceTestCase;
+import com.example.android.newalarm.AlarmService;
+
+/**
+ * Test class for the Alarm sample test package. This test class tests the AlarmService
+ * service component.
+ */
+public class AlarmServiceTest extends ServiceTestCase<AlarmService> {
+    // Contains an Intent used to start the service
+    Intent mStartServiceIntent;
+
+    // Contains a handle to the system alarm service
+    AlarmService mService;
+
+    /**
+     * Constructor for the test class. Test classes that are run by InstrumentationTestRunner
+     * must provide a constructor with no arguments that calls the base class constructor as its
+     * first statement.
+     */
+    public AlarmServiceTest() {
+        super(AlarmService.class);
+    }
+
+    /*
+     * Sets up the test fixture. This method is called before each test
+     */
+    @Override
+    protected void setUp() throws Exception {
+
+        super.setUp();
+
+        // Sets up an intent to start the service under test
+        mStartServiceIntent = new Intent(this.getSystemContext(),AlarmService.class);
+    }
+
+    /**
+     * Cleans up the test fixture
+     * Called after each test method. If you override the method, call super.tearDown() as the
+     * last statement in your override.
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        // Always call the super constructor when overriding tearDown()
+        super.tearDown();
+    }
+
+    /**
+     * Tests the service's onCreate() method. Starts the service using startService(Intent)
+     */
+    public void testServiceCreate() {
+        // Starts the service under test
+        this.startService(mStartServiceIntent);
+
+        // Gets a handle to the service under test.
+        mService = this.getService();
+
+        // Asserts that the Notification Manager was created in the service under test.
+        assertNotNull(mService.mNotificationManager);
+
+        // Asserts that the PendingIntent for the expanded status window was created
+        assertNotNull(mService.mContentIntent);
+
+        // Asserts that the notification was created
+        assertNotNull(mService.mNotification);
+    }
+
+}