1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/*
2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project
3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License");
5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License.
6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at
7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *      http://www.apache.org/licenses/LICENSE-2.0
9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software
11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS,
12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and
14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License.
15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.datamodel.action;
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Intent;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Bundle;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Looper;
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Parcel;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Parcelable;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Process;
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.test.suitebuilder.annotation.MediumTest;
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.util.Log;
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.Factory;
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.FakeContext;
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.FakeContext.FakeContextHost;
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.FakeFactory;
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.BugleServiceTestCase;
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.FakeDataModel;
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.action.ActionMonitor.ActionCompletedListener;
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.action.ActionMonitor.ActionStateChangedListener;
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.action.ActionTestHelpers.ResultTracker;
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.action.ActionTestHelpers.StubBackgroundWorker;
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.action.ActionTestHelpers.StubConnectivityUtil;
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.action.ActionTestHelpers.StubLoader;
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.WakeLockHelper;
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.ArrayList;
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd@MediumTest
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class ActionServiceTest extends BugleServiceTestCase<ActionServiceImpl>
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        implements FakeContextHost, ActionStateChangedListener, ActionCompletedListener {
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String TAG = "ActionServiceTest";
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onActionStateChanged(final Action action, final int state) {
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mStates.add(state);
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onActionSucceeded(final ActionMonitor monitor,
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Action action, final Object data, final Object result) {
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final TestChatAction test = (TestChatAction) action;
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertNotSame(test.dontRelyOnMe, dontRelyOnMe);
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // This will be true - but only briefly
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertEquals(test.dontRelyOnMe, becauseIChange);
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final ResultTracker tracker = (ResultTracker) data;
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        tracker.completionResult = result;
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        synchronized(tracker) {
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            tracker.notifyAll();
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onActionFailed(final ActionMonitor monitor, final Action action,
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Object data, final Object result) {
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final TestChatAction test = (TestChatAction) action;
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertNotSame(test.dontRelyOnMe, dontRelyOnMe);
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // This will be true - but only briefly
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertEquals(test.dontRelyOnMe, becauseIChange);
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final ResultTracker tracker = (ResultTracker) data;
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        tracker.completionResult = result;
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        synchronized(tracker) {
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            tracker.notifyAll();
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * For a dummy action verify that the service intent is constructed and queued correctly and
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * that when that intent is processed it actually executes the action.
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void testChatServiceCreatesIntentAndExecutesAction() {
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final ResultTracker tracker = new ResultTracker();
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final TestChatActionMonitor monitor = new TestChatActionMonitor(null, tracker, this, this);
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final TestChatAction action = new TestChatAction(monitor.getActionKey(), parameter);
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        action.dontRelyOnMe = dontRelyOnMe;
95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertFalse("Expect service initially stopped", mServiceStarted);
96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        action.start(monitor);
98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertTrue("Expect service started", mServiceStarted);
100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final ArrayList<Intent> intents = mContext.extractIntents();
102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertNotNull(intents);
103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertEquals("Expect to see 1 server request queued", 1, intents.size());
104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = intents.get(0);
105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertEquals("Check pid", intent.getIntExtra(WakeLockHelper.EXTRA_CALLING_PID, 0),
106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                Process.myPid());
107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertEquals("Check opcode", intent.getIntExtra(ActionServiceImpl.EXTRA_OP_CODE, 0),
108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                ActionServiceImpl.OP_START_ACTION);
109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertTrue("Check wakelock held", ActionServiceImpl.sWakeLock.isHeld(intent));
110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        synchronized(tracker) {
112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            try {
113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                this.startService(intent);
114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Wait for callback across threads
115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                tracker.wait(2000);
116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } catch (final InterruptedException e) {
117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                assertTrue("Interrupted waiting for response processing", false);
118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertEquals("Expect three states ", mStates.size(), 3);
122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertEquals("State-0 should be STATE_QUEUED", (int)mStates.get(0),
123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                ActionMonitor.STATE_QUEUED);
124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertEquals("State-1 should be STATE_EXECUTING", (int)mStates.get(1),
125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                ActionMonitor.STATE_EXECUTING);
126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertEquals("State-2 should be STATE_COMPLETE", (int)mStates.get(2),
127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                ActionMonitor.STATE_COMPLETE);
128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // TODO: Should find a way to reliably wait, this is a bit of a hack
129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (ActionServiceImpl.sWakeLock.isHeld(intent)) {
130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            Log.d(TAG, "ActionServiceTest: waiting for wakelock release");
131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            try {
132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                Thread.sleep(100);
133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } catch (final InterruptedException e) {
134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertFalse("Check wakelock released", ActionServiceImpl.sWakeLock.isHeld(intent));
137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    StubBackgroundWorker mWorker;
140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    FakeContext mContext;
141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    StubLoader mLoader;
142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    ActionService mService;
143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    ArrayList<Integer> mStates;
145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String parameter = "parameter";
147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final Object dontRelyOnMe = "dontRelyOnMe";
148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final Object becauseIChange = "becauseIChange";
149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final Object executeActionResult = "executeActionResult";
150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final Object processResponseResult = "processResponseResult";
151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final Object processFailureResult = "processFailureResult";
152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public ActionServiceTest() {
154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super(ActionServiceImpl.class);
155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void setUp() throws Exception {
159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super.setUp();
160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        Log.d(TAG, "ChatActionTest setUp");
161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        sLooper = Looper.myLooper();
163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mWorker = new StubBackgroundWorker();
165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mContext = new FakeContext(getContext(), this);
166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        FakeFactory.registerWithFakeContext(getContext(),mContext)
167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .withDataModel(new FakeDataModel(mContext)
168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .withBackgroundWorkerForActionService(mWorker)
169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .withActionService(new ActionService())
170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .withConnectivityUtil(new StubConnectivityUtil(mContext)));
171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mStates = new ArrayList<Integer>();
173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        setContext(Factory.get().getApplicationContext());
174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public String getServiceClassName() {
178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return ActionServiceImpl.class.getName();
179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    boolean mServiceStarted = false;
182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void startServiceForStub(final Intent intent) {
185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Do nothing until later
186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertFalse(mServiceStarted);
187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mServiceStarted = true;
188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onStartCommandForStub(final Intent intent, final int flags, final int startId) {
192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertTrue(mServiceStarted);
193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static Looper sLooper;
196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static void assertRunsOnOtherThread() {
197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertTrue (Looper.myLooper() != Looper.getMainLooper());
198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        assertTrue (Looper.myLooper() != sLooper);
199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static class TestChatAction extends Action implements Parcelable {
202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public static String RESPONSE_TEST = "response_test";
203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public static String KEY_PARAMETER = "parameter";
204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        protected TestChatAction(final String key, final String parameter) {
206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            super(key);
207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            this.actionParameters.putString(KEY_PARAMETER, parameter);
208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        transient Object dontRelyOnMe;
211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        /**
213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         * Process the action locally - runs on service thread
214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         */
215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        protected Object executeAction() {
217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            this.dontRelyOnMe = becauseIChange;
218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            assertRunsOnOtherThread();
219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return executeActionResult;
220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        /**
223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         * Process the response from the server - runs on service thread
224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         */
225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        protected Object processBackgroundResponse(final Bundle response) {
227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            assertRunsOnOtherThread();
228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return processResponseResult;
229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        /**
232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         * Called in case of failures when sending requests - runs on service thread
233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         */
234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        protected Object processBackgroundFailure() {
236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            assertRunsOnOtherThread();
237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return processFailureResult;
238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private TestChatAction(final Parcel in) {
241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            super(in);
242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public static final Parcelable.Creator<TestChatAction> CREATOR
245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                = new Parcelable.Creator<TestChatAction>() {
246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public TestChatAction createFromParcel(final Parcel in) {
248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return new TestChatAction(in);
249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public TestChatAction[] newArray(final int size) {
253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return new TestChatAction[size];
254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        };
256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public void writeToParcel(final Parcel parcel, final int flags) {
259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            writeActionToParcel(parcel, flags);
260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * An operation that notifies a listener upon state changes, execution and completion
265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static class TestChatActionMonitor extends ActionMonitor {
267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public TestChatActionMonitor(final String baseKey, final Object data,
268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final ActionStateChangedListener listener, final ActionCompletedListener executed) {
269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            super(STATE_CREATED, Action.generateUniqueActionKey(baseKey), data);
270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            setStateChangedListener(listener);
271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            setCompletedListener(executed);
272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            assertEquals("Initial state should be STATE_CREATED", mState, STATE_CREATED);
273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
276