Bug: 316941721 Test: mmma . Change-Id: I102674aa519cf562aa8d0b852ebb8067748894a6
253 lines
8.9 KiB
Java
253 lines
8.9 KiB
Java
/*
|
|
* Copyright (C) 2015 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.messaging.datamodel.action;
|
|
|
|
import android.content.Intent;
|
|
import android.os.Bundle;
|
|
import android.os.Looper;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.util.Log;
|
|
|
|
import androidx.test.filters.MediumTest;
|
|
|
|
import com.android.messaging.Factory;
|
|
import com.android.messaging.FakeContext;
|
|
import com.android.messaging.FakeContext.FakeContextHost;
|
|
import com.android.messaging.FakeFactory;
|
|
import com.android.messaging.datamodel.BugleServiceTestCase;
|
|
import com.android.messaging.datamodel.FakeDataModel;
|
|
import com.android.messaging.datamodel.action.ActionMonitor.ActionCompletedListener;
|
|
import com.android.messaging.datamodel.action.ActionMonitor.ActionStateChangedListener;
|
|
import com.android.messaging.datamodel.action.ActionTestHelpers.ResultTracker;
|
|
import com.android.messaging.datamodel.action.ActionTestHelpers.StubBackgroundWorker;
|
|
import com.android.messaging.datamodel.action.ActionTestHelpers.StubLoader;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
@MediumTest
|
|
public class ActionServiceTest extends BugleServiceTestCase<ActionServiceImpl>
|
|
implements FakeContextHost, ActionStateChangedListener, ActionCompletedListener {
|
|
private static final String TAG = "ActionServiceTest";
|
|
|
|
@Override
|
|
public void onActionStateChanged(final Action action, final int state) {
|
|
mStates.add(state);
|
|
}
|
|
|
|
@Override
|
|
public void onActionSucceeded(final ActionMonitor monitor,
|
|
final Action action, final Object data, final Object result) {
|
|
final TestChatAction test = (TestChatAction) action;
|
|
assertNotSame(test.dontRelyOnMe, dontRelyOnMe);
|
|
// This will be true - but only briefly
|
|
assertEquals(test.dontRelyOnMe, becauseIChange);
|
|
|
|
final ResultTracker tracker = (ResultTracker) data;
|
|
tracker.completionResult = result;
|
|
synchronized(tracker) {
|
|
tracker.notifyAll();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onActionFailed(final ActionMonitor monitor, final Action action,
|
|
final Object data, final Object result) {
|
|
final TestChatAction test = (TestChatAction) action;
|
|
assertNotSame(test.dontRelyOnMe, dontRelyOnMe);
|
|
// This will be true - but only briefly
|
|
assertEquals(test.dontRelyOnMe, becauseIChange);
|
|
|
|
final ResultTracker tracker = (ResultTracker) data;
|
|
tracker.completionResult = result;
|
|
synchronized(tracker) {
|
|
tracker.notifyAll();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* For a chat action verify that the service intent is constructed and queued correctly and
|
|
* that when that intent is processed it actually executes the action.
|
|
*/
|
|
public void testChatServiceCreatesIntentAndExecutesAction() {
|
|
final ResultTracker tracker = new ResultTracker();
|
|
|
|
final TestChatActionMonitor monitor = new TestChatActionMonitor(null, tracker, this, this);
|
|
final TestChatAction action = new TestChatAction(monitor.getActionKey(), parameter);
|
|
|
|
action.dontRelyOnMe = dontRelyOnMe;
|
|
assertFalse("Expect service initially stopped", mServiceStarted);
|
|
|
|
synchronized(mWorker) {
|
|
try {
|
|
action.start(monitor);
|
|
// Wait for callback across threads
|
|
mWorker.wait(2000);
|
|
mServiceStarted = true;
|
|
} catch (final InterruptedException e) {
|
|
assertTrue("Interrupted waiting for execution", false);
|
|
}
|
|
}
|
|
|
|
assertTrue("Expect service started", mServiceStarted);
|
|
|
|
assertEquals("Expect three states ", mStates.size(), 3);
|
|
assertEquals("State-0 should be STATE_QUEUED", (int)mStates.get(0),
|
|
ActionMonitor.STATE_QUEUED);
|
|
assertEquals("State-1 should be STATE_EXECUTING", (int)mStates.get(1),
|
|
ActionMonitor.STATE_EXECUTING);
|
|
assertEquals("State-2 should be STATE_COMPLETE", (int)mStates.get(2),
|
|
ActionMonitor.STATE_COMPLETE);
|
|
}
|
|
|
|
StubBackgroundWorker mWorker;
|
|
FakeContext mContext;
|
|
StubLoader mLoader;
|
|
ActionService mService;
|
|
|
|
ArrayList<Integer> mStates;
|
|
|
|
private static final String parameter = "parameter";
|
|
private static final Object dontRelyOnMe = "dontRelyOnMe";
|
|
private static final Object becauseIChange = "becauseIChange";
|
|
private static final Object executeActionResult = "executeActionResult";
|
|
private static final Object processResponseResult = "processResponseResult";
|
|
private static final Object processFailureResult = "processFailureResult";
|
|
|
|
public ActionServiceTest() {
|
|
super(ActionServiceImpl.class);
|
|
}
|
|
|
|
@Override
|
|
public void setUp() throws Exception {
|
|
super.setUp();
|
|
Log.d(TAG, "ChatActionTest setUp");
|
|
|
|
sLooper = Looper.myLooper();
|
|
|
|
mWorker = new StubBackgroundWorker();
|
|
mContext = new FakeContext(getContext(), this);
|
|
FakeFactory.registerWithFakeContext(getContext(),mContext)
|
|
.withDataModel(new FakeDataModel(mContext)
|
|
.withBackgroundWorkerForActionService(mWorker)
|
|
.withActionService(new ActionService()));
|
|
|
|
mStates = new ArrayList<Integer>();
|
|
setContext(Factory.get().getApplicationContext());
|
|
}
|
|
|
|
@Override
|
|
public String getServiceClassName() {
|
|
return ActionServiceImpl.class.getName();
|
|
}
|
|
|
|
boolean mServiceStarted = false;
|
|
|
|
@Override
|
|
public void startServiceForStub(final Intent intent) {
|
|
// Do nothing until later
|
|
assertFalse(mServiceStarted);
|
|
mServiceStarted = true;
|
|
}
|
|
|
|
@Override
|
|
public void onStartCommandForStub(final Intent intent, final int flags, final int startId) {
|
|
assertTrue(mServiceStarted);
|
|
}
|
|
|
|
private static Looper sLooper;
|
|
public static void assertRunsOnOtherThread() {
|
|
assertTrue (Looper.myLooper() != Looper.getMainLooper());
|
|
assertTrue (Looper.myLooper() != sLooper);
|
|
}
|
|
|
|
public static class TestChatAction extends Action implements Parcelable {
|
|
public static String RESPONSE_TEST = "response_test";
|
|
public static String KEY_PARAMETER = "parameter";
|
|
|
|
protected TestChatAction(final String key, final String parameter) {
|
|
super(key);
|
|
this.actionParameters.putString(KEY_PARAMETER, parameter);
|
|
}
|
|
|
|
transient Object dontRelyOnMe;
|
|
|
|
/**
|
|
* Process the action locally - runs on service thread
|
|
*/
|
|
@Override
|
|
protected Object executeAction() {
|
|
this.dontRelyOnMe = becauseIChange;
|
|
assertRunsOnOtherThread();
|
|
return executeActionResult;
|
|
}
|
|
|
|
/**
|
|
* Process the response from the server - runs on service thread
|
|
*/
|
|
@Override
|
|
protected Object processBackgroundResponse(final Bundle response) {
|
|
assertRunsOnOtherThread();
|
|
return processResponseResult;
|
|
}
|
|
|
|
/**
|
|
* Called in case of failures when sending requests - runs on service thread
|
|
*/
|
|
@Override
|
|
protected Object processBackgroundFailure() {
|
|
assertRunsOnOtherThread();
|
|
return processFailureResult;
|
|
}
|
|
|
|
private TestChatAction(final Parcel in) {
|
|
super(in);
|
|
}
|
|
|
|
public static final Parcelable.Creator<TestChatAction> CREATOR
|
|
= new Parcelable.Creator<TestChatAction>() {
|
|
@Override
|
|
public TestChatAction createFromParcel(final Parcel in) {
|
|
return new TestChatAction(in);
|
|
}
|
|
|
|
@Override
|
|
public TestChatAction[] newArray(final int size) {
|
|
return new TestChatAction[size];
|
|
}
|
|
};
|
|
|
|
@Override
|
|
public void writeToParcel(final Parcel parcel, final int flags) {
|
|
writeActionToParcel(parcel, flags);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An operation that notifies a listener upon state changes, execution and completion
|
|
*/
|
|
public static class TestChatActionMonitor extends ActionMonitor {
|
|
public TestChatActionMonitor(final String baseKey, final Object data,
|
|
final ActionStateChangedListener listener, final ActionCompletedListener executed) {
|
|
super(STATE_CREATED, Action.generateUniqueActionKey(baseKey), data);
|
|
setStateChangedListener(listener);
|
|
setCompletedListener(executed);
|
|
assertEquals("Initial state should be STATE_CREATED", mState, STATE_CREATED);
|
|
}
|
|
}
|
|
}
|