Integrate unsubmitted cupcake change 143447:
	CTS: add testcase android.telephony.cts.PhoneStateListenerTest
diff --git a/tests/tests/telephony/Android.mk b/tests/tests/telephony/Android.mk
new file mode 100644
index 0000000..62b256e
--- /dev/null
+++ b/tests/tests/telephony/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2008 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.
+
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsTelephonyTestCases
+
+LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
diff --git a/tests/tests/telephony/AndroidManifest.xml b/tests/tests/telephony/AndroidManifest.xml
new file mode 100644
index 0000000..a565fad
--- /dev/null
+++ b/tests/tests/telephony/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.telephony">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="com.android.cts.stub"
+                     android:label="CTS tests of android.telephony"/>
+
+</manifest>
+
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
new file mode 100644
index 0000000..b6c3d2a
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2009 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 android.telephony.cts;
+
+import android.content.Context;
+import android.os.Looper;
+import android.os.cts.TestThread;
+import android.telephony.CellLocation;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(PhoneStateListener.class)
+public class PhoneStateListenerTest extends AndroidTestCase {
+
+    public static final long WAIT_TIME = 1000;
+
+    private boolean mOnCallForwardingIndicatorChangedCalled;
+    private boolean mOnCallStateChangedCalled;
+    private boolean mOnCellLocationChangedCalled;
+    private boolean mOnDataActivityCalled;
+    private boolean mOnDataConnectionStateChangedCalled;
+    private boolean mOnMessageWaitingIndicatorChangedCalled;
+    private boolean mOnServiceStateChangedCalled;
+    private boolean mOnSignalStrengthChangedCalled;
+    private TelephonyManager mTelephonyManager;
+    private PhoneStateListener mListener;
+    private final Object mLock = new Object();
+    private Looper mLooper;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        Context context = getContext();
+        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (mLooper != null) {
+            mLooper.quit();
+        }
+        if (mListener != null) {
+            // unregister the listener
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
+        }
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            notes = "Test constructor(s) of {@link PhoneStateListener}",
+            method = "PhoneStateListener",
+            args = {}
+        )
+    })
+    public void testPhoneStateListener() {
+        new PhoneStateListener();
+    }
+
+    /*
+     * The tests below rely on the framework to immediately call the installed listener upon
+     * registration. There is no simple way to emulate state changes for testing the listeners.
+     */
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            notes = "Test method: onServiceStateChanged ",
+            method = "onServiceStateChanged",
+            args = {ServiceState.class}
+        )
+    })
+    public void testOnServiceStateChanged() throws Throwable {
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+                mLooper = Looper.myLooper();
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onServiceStateChanged(ServiceState serviceState) {
+                        synchronized(mLock) {
+                            mOnServiceStateChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnServiceStateChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            while(!mOnServiceStateChangedCalled){
+                mLock.wait();
+            }
+        }
+        quitLooper();
+        t.checkException();
+        assertTrue(mOnServiceStateChangedCalled);
+    }
+
+    private void quitLooper() {
+        mLooper.quit();
+        mLooper = null;
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            notes = "Test method: onSignalStrengthChanged ",
+            method = "onSignalStrengthChanged",
+            args = {int.class}
+        )
+    })
+    public void testOnSignalStrengthChanged() throws Throwable {
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mLooper = Looper.myLooper();
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onSignalStrengthChanged(int asu) {
+                        synchronized(mLock) {
+                            mOnSignalStrengthChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnSignalStrengthChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            while(!mOnSignalStrengthChangedCalled){
+                mLock.wait();
+            }
+        }
+        quitLooper();
+        t.checkException();
+        assertTrue(mOnSignalStrengthChangedCalled);
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            notes = "Test method: onMessageWaitingIndicatorChanged ",
+            method = "onMessageWaitingIndicatorChanged",
+            args = {boolean.class}
+        )
+    })
+    public void testOnMessageWaitingIndicatorChanged() throws Throwable {
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mLooper = Looper.myLooper();
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onMessageWaitingIndicatorChanged(boolean mwi) {
+                        synchronized(mLock) {
+                            mOnMessageWaitingIndicatorChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(
+                        mListener, PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnMessageWaitingIndicatorChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            while(!mOnMessageWaitingIndicatorChangedCalled){
+                mLock.wait();
+            }
+        }
+        quitLooper();
+        t.checkException();
+        assertTrue(mOnMessageWaitingIndicatorChangedCalled);
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            notes = "Test method: onCallForwardingIndicatorChanged ",
+            method = "onCallForwardingIndicatorChanged",
+            args = {boolean.class}
+        )
+    })
+    public void testOnCallForwardingIndicatorChanged() throws Throwable {
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mLooper = Looper.myLooper();
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onCallForwardingIndicatorChanged(boolean cfi) {
+                        synchronized(mLock) {
+                            mOnCallForwardingIndicatorChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(
+                        mListener, PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnCallForwardingIndicatorChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            while(!mOnCallForwardingIndicatorChangedCalled){
+                mLock.wait();
+            }
+        }
+        quitLooper();
+        t.checkException();
+        assertTrue(mOnCallForwardingIndicatorChangedCalled);
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            notes = "Test method: onCellLocationChanged ",
+            method = "onCellLocationChanged",
+            args = {CellLocation.class}
+        )
+    })
+    public void testOnCellLocationChanged() throws Throwable {
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mLooper = Looper.myLooper();
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onCellLocationChanged(CellLocation location) {
+                        synchronized(mLock) {
+                            mOnCellLocationChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnCellLocationChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            while(!mOnCellLocationChangedCalled){
+                mLock.wait();
+            }
+        }
+        quitLooper();
+        t.checkException();
+        assertTrue(mOnCellLocationChangedCalled);
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            notes = "Test method: onCallStateChanged ",
+            method = "onCallStateChanged",
+            args = {int.class, String.class}
+        )
+    })
+    public void testOnCallStateChanged() throws Throwable {
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mLooper = Looper.myLooper();
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onCallStateChanged(int state, String incomingNumber) {
+                        synchronized(mLock) {
+                            mOnCallStateChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnCallStateChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            while(!mOnCallStateChangedCalled){
+                mLock.wait();
+            }
+        }
+        quitLooper();
+        t.checkException();
+        assertTrue(mOnCallStateChangedCalled);
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            notes = "Test method: onDataConnectionStateChanged ",
+            method = "onDataConnectionStateChanged",
+            args = {int.class}
+        )
+    })
+    public void testOnDataConnectionStateChanged() throws Throwable {
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mLooper = Looper.myLooper();
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onDataConnectionStateChanged(int state) {
+                        synchronized(mLock) {
+                            mOnDataConnectionStateChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(
+                        mListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnDataConnectionStateChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            while(!mOnDataConnectionStateChangedCalled){
+                mLock.wait();
+            }
+        }
+        quitLooper();
+        t.checkException();
+        assertTrue(mOnDataConnectionStateChangedCalled);
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            notes = "Test method: onDataActivity ",
+            method = "onDataActivity",
+            args = {int.class}
+        )
+    })
+    public void testOnDataActivity() throws Throwable {
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mLooper = Looper.myLooper();
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onDataActivity(int direction) {
+                        synchronized(mLock) {
+                            mOnDataActivityCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_DATA_ACTIVITY);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnDataActivityCalled);
+        t.start();
+
+        synchronized (mLock) {
+            while(!mOnDataActivityCalled){
+                mLock.wait();
+            }
+        }
+        quitLooper();
+        t.checkException();
+        assertTrue(mOnDataActivityCalled);
+    }
+}