blob: 1f96ccd993c549876f5d6b1aad284131340e712b [file] [log] [blame]
// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// 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 dev.cobalt.coat;
import static dev.cobalt.util.Log.TAG;
import dev.cobalt.util.Log;
import dev.cobalt.util.UsedByNative;
/** Abstract class that provides an interface for Cobalt to interact with a platform service. */
public abstract class CobaltService {
// Indicate is the service opened, and be able to send data to client
protected boolean opened = true;
/** Interface that returns an object that extends CobaltService. */
public interface Factory {
/** Create the service. */
public CobaltService createCobaltService(long nativeService);
/** Get the name of the service. */
public String getServiceName();
}
/** Take in a reference to StarboardBridge & use it as needed. Default behavior is no-op. */
public void receiveStarboardBridge(StarboardBridge bridge) {}
// Lifecycle
/** Prepare service for start or resume. */
public abstract void beforeStartOrResume();
/** Prepare service for suspend. */
public abstract void beforeSuspend();
/** Prepare service for stop. */
public abstract void afterStopped();
// Service API
/** Response to client from calls to receiveFromClient(). */
@SuppressWarnings("unused")
@UsedByNative
public static class ResponseToClient {
/** Indicate if the service was unable to receive data because it is in an invalid state. */
@SuppressWarnings("unused")
@UsedByNative
public boolean invalidState;
/** The synchronous response data from the service. */
@SuppressWarnings("unused")
@UsedByNative
public byte[] data;
}
/** Receive data from client of the service. */
@SuppressWarnings("unused")
@UsedByNative
public abstract ResponseToClient receiveFromClient(byte[] data);
/**
* Close the service.
*
* <p>Once this function returns, it is invalid to call sendToClient for the nativeService, so
* synchronization must be used to protect against this.
*/
@SuppressWarnings("unused")
@UsedByNative
public void onClose() {
synchronized (this) {
opened = false;
close();
}
}
public abstract void close();
/**
* Send data from the service to the client.
*
* <p>This may be called from a separate thread, do not call nativeSendToClient() once onClose()
* is processed.
*/
protected void sendToClient(long nativeService, byte[] data) {
synchronized (this) {
if (!opened) {
Log.w(
TAG,
"Platform service did not send data to client, because client already closed the"
+ " platform service.");
return;
}
nativeSendToClient(nativeService, data);
}
}
private native void nativeSendToClient(long nativeService, byte[] data);
}