blob: 599f08ba7df0687f367232e8bdfec3002ddb3508 [file] [log] [blame]
/*
* Copyright (C) 2023 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.phone.testapps.satellitetestapp;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.telephony.satellite.PointingInfo;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteDatagramCallback;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteStateCallback;
import android.telephony.satellite.SatelliteTransmissionUpdateCallback;
import android.telephony.satellite.stub.SatelliteError;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import java.util.LinkedList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
/**
* Activity related to Datagram APIs.
*/
public class Datagram extends Activity {
private static final String TAG = "Datagram";
private static final int MAX_NUMBER_OF_STORED_STATES = 3;
private int mTransferState;
private int mModemState;
LinkedList<Integer> mModemStateQueue = new LinkedList<>();
LinkedList<Integer> mSendQueue = new LinkedList<>();
LinkedList<Integer> mReceiveQueue = new LinkedList<>();
private SatelliteManager mSatelliteManager;
private SatelliteDatagramCallbackTestApp mDatagramCallback;
private SatelliteStateCallbackTestApp mStateCallback;
private SatelliteTransmissionUpdateCallbackTestApp mCallback;
private android.telephony.satellite.stub.SatelliteDatagram mReceivedDatagram;
private String mShowSatelliteModemStateTransition;
private String mShowDatagramSendStateTransition;
private String mShowDatagramReceiveStateTransition;
private static final long TIMEOUT = 3000;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSatelliteManager = getSystemService(SatelliteManager.class);
mDatagramCallback = new SatelliteDatagramCallbackTestApp();
mStateCallback = new SatelliteStateCallbackTestApp();
mCallback = new SatelliteTransmissionUpdateCallbackTestApp();
mReceivedDatagram = new android.telephony.satellite.stub.SatelliteDatagram();
setContentView(R.layout.activity_Datagram);
findViewById(R.id.startSatelliteTransmissionUpdates)
.setOnClickListener(this::startSatelliteTransmissionUpdatesApp);
findViewById(R.id.stopSatelliteTransmissionUpdates)
.setOnClickListener(this::stopSatelliteTransmissionUpdatesApp);
findViewById(R.id.pollPendingSatelliteDatagrams)
.setOnClickListener(this::pollPendingSatelliteDatagramsApp);
findViewById(R.id.sendSatelliteDatagram)
.setOnClickListener(this::sendSatelliteDatagramApp);
findViewById(R.id.registerForSatelliteDatagram)
.setOnClickListener(this::registerForSatelliteDatagramApp);
findViewById(R.id.unregisterForSatelliteDatagram)
.setOnClickListener(this::unregisterForSatelliteDatagramApp);
findViewById(R.id.showDatagramSendStateTransition)
.setOnClickListener(this::showDatagramSendStateTransitionApp);
findViewById(R.id.showDatagramReceiveStateTransition)
.setOnClickListener(this::showDatagramReceiveStateTransitionApp);
findViewById(R.id.registerForSatelliteModemStateChanged)
.setOnClickListener(this::registerForSatelliteModemStateChangedApp);
findViewById(R.id.unregisterForSatelliteModemStateChanged)
.setOnClickListener(this::unregisterForSatelliteModemStateChangedApp);
findViewById(R.id.showSatelliteModemStateTransition)
.setOnClickListener(this::showSatelliteModemStateTransitionApp);
findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(Datagram.this, SatelliteTestApp.class));
}
});
}
protected class SatelliteDatagramCallbackTestApp implements SatelliteDatagramCallback {
@Override
public void onSatelliteDatagramReceived(long datagramId, SatelliteDatagram datagram,
int pendingCount, Consumer<Void> callback) {
Log.d(TAG, "onSatelliteDatagramReceived in TestApp: datagramId =" + datagramId
+ ", datagram =" + datagram + ", pendingCount=" + pendingCount);
}
}
protected class SatelliteStateCallbackTestApp implements SatelliteStateCallback {
@Override
public void onSatelliteModemStateChanged(int state) {
mModemState = state;
mModemStateQueue.addLast(state);
if (mModemStateQueue.size() > MAX_NUMBER_OF_STORED_STATES) {
mModemStateQueue.removeFirst();
}
mShowSatelliteModemStateTransition = getSatelliteModemStateTransition(mModemStateQueue);
Log.d(TAG, "onSatelliteModemStateChanged in TestApp: state=" + mModemState);
}
}
protected class SatelliteTransmissionUpdateCallbackTestApp implements
SatelliteTransmissionUpdateCallback {
@Override
public void onSatellitePositionChanged(PointingInfo pointingInfo) {
Log.d(TAG, "onSatellitePositionChanged in TestApp: pointingInfo =" + pointingInfo);
}
@Override
public void onSendDatagramStateChanged(int state, int sendPendingCount, int errorCode) {
mTransferState = state;
mSendQueue.addLast(state);
if (mSendQueue.size() > MAX_NUMBER_OF_STORED_STATES) {
mSendQueue.removeFirst();
}
mShowDatagramSendStateTransition = getTransferStateTransition(mSendQueue);
Log.d(TAG, "onSendDatagramStateChanged in TestApp: state =" + mTransferState
+ ", sendPendingCount =" + sendPendingCount + ", errorCode=" + errorCode);
}
@Override
public void onReceiveDatagramStateChanged(
int state, int receivePendingCount, int errorCode) {
mTransferState = state;
mReceiveQueue.addLast(state);
if (mReceiveQueue.size() > MAX_NUMBER_OF_STORED_STATES) {
mReceiveQueue.removeFirst();
}
mShowDatagramReceiveStateTransition = getTransferStateTransition(mReceiveQueue);
Log.d(TAG, "onReceiveDatagramStateChanged in TestApp: state=" + mTransferState
+ ", receivePendingCount=" + receivePendingCount + ", errorCode=" + errorCode);
}
}
private void startSatelliteTransmissionUpdatesApp(View view) {
TextView textView = findViewById(R.id.text_id);
LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
mSatelliteManager.requestSatelliteEnabled(true, true, Runnable::run, error::offer);
TextView showErrorStatusTextView = findViewById(R.id.showErrorStatus);
try {
Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
if (value == null) {
showErrorStatusTextView.setText("Timed out to enable the satellite");
return;
} else if (value != SatelliteError.ERROR_NONE) {
showErrorStatusTextView.setText("Failed to enable satellite, error = "
+ SatelliteErrorUtils.mapError(value));
return;
}
} catch (InterruptedException e) {
showErrorStatusTextView.setText("Enable SatelliteService exception caught = " + e);
return;
}
error.clear();
mSatelliteManager.startSatelliteTransmissionUpdates(Runnable::run, error::offer, mCallback);
try {
Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
if (value == null) {
textView.setText("Timed out to startSatelliteTransmissionUpdates");
} else if (value != SatelliteError.ERROR_NONE) {
textView.setText("Failed to startSatelliteTransmissionUpdates with error = "
+ SatelliteErrorUtils.mapError(value));
} else {
textView.setText("startSatelliteTransmissionUpdates is successful");
}
} catch (InterruptedException e) {
textView.setText("startSatelliteTransmissionUpdates exception caught =" + e);
}
}
private void stopSatelliteTransmissionUpdatesApp(View view) {
TextView textView = findViewById(R.id.text_id);
LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
mSatelliteManager.stopSatelliteTransmissionUpdates(mCallback, Runnable::run, error::offer);
try {
Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
if (value == null) {
textView.setText("Timed out to stopSatelliteTransmissionUpdates");
} else if (value != SatelliteError.ERROR_NONE) {
textView.setText("Failed to stopSatelliteTransmissionUpdates with error = "
+ SatelliteErrorUtils.mapError(value));
} else {
textView.setText("stopSatelliteTransmissionUpdates is successful");
}
} catch (InterruptedException e) {
textView.setText("stopSatelliteTransmissionUpdates exception caught =" + e);
}
}
private void pollPendingSatelliteDatagramsApp(View view) {
LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
TextView showErrorStatusTextView = findViewById(R.id.showErrorStatus);
TextView textView = findViewById(R.id.text_id);
mSatelliteManager.onDeviceAlignedWithSatellite(true);
if (SatelliteTestApp.getTestSatelliteService() != null) {
SatelliteTestApp.getTestSatelliteService().sendOnPendingDatagrams();
}
mSatelliteManager.requestSatelliteEnabled(true, true, Runnable::run, resultListener::offer);
try {
Integer value = resultListener.poll(TIMEOUT, TimeUnit.MILLISECONDS);
if (value == null) {
showErrorStatusTextView.setText("Timed out to enable the satellite");
return;
} else if (value != SatelliteError.ERROR_NONE) {
showErrorStatusTextView.setText("Failed to enable satellite, error = "
+ SatelliteErrorUtils.mapError(value));
return;
}
resultListener.clear();
Log.d(TAG, "Poll to check queue is cleared = "
+ resultListener.poll(TIMEOUT, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {
showErrorStatusTextView.setText("Enable SatelliteService exception caught = " + e);
return;
}
mSatelliteManager.pollPendingSatelliteDatagrams(Runnable::run, resultListener::offer);
try {
Integer value = resultListener.poll(TIMEOUT, TimeUnit.MILLISECONDS);
if (value == null) {
textView.setText("Timed out for poll message");
} else if (value != SatelliteError.ERROR_NONE) {
textView.setText("Failed to pollPendingSatelliteDatagrams with error = "
+ SatelliteErrorUtils.mapError(value));
} else {
textView.setText("pollPendingSatelliteDatagrams is successful");
}
} catch (InterruptedException e) {
textView.setText("pollPendingSatelliteDatagrams exception caught =" + e);
}
}
private void sendSatelliteDatagramApp(View view) {
TextView textView = findViewById(R.id.text_id);
mSatelliteManager.onDeviceAlignedWithSatellite(true);
LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
String mText = "This is a test datagram message";
SatelliteDatagram datagram = new SatelliteDatagram(mText.getBytes());
mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
datagram, true, Runnable::run, resultListener::offer);
try {
Integer value = resultListener.poll(TIMEOUT, TimeUnit.MILLISECONDS);
if (value == null) {
textView.setText("Timed out for sendSatelliteDatagram");
} else if (value != SatelliteError.ERROR_NONE) {
textView.setText("Failed to sendSatelliteDatagram with error = "
+ SatelliteErrorUtils.mapError(value));
} else {
textView.setText("sendSatelliteDatagram is successful");
}
} catch (InterruptedException e) {
textView.setText("sendSatelliteDatagram exception caught =" + e);
}
}
private void registerForSatelliteDatagramApp(View view) {
int result = mSatelliteManager.registerForSatelliteDatagram(Runnable::run,
mDatagramCallback);
TextView textView = findViewById(R.id.text_id);
if (result == 0) {
textView.setText("registerForSatelliteDatagram is successful");
} else {
textView.setText("Status for registerForSatelliteDatagram : "
+ SatelliteErrorUtils.mapError(result));
}
}
private void unregisterForSatelliteDatagramApp(View view) {
mSatelliteManager.unregisterForSatelliteDatagram(mDatagramCallback);
TextView textView = findViewById(R.id.text_id);
textView.setText("unregisterForSatelliteDatagram is successful");
}
private void showDatagramSendStateTransitionApp(View view) {
TextView textView = findViewById(R.id.text_id);
textView.setText("Last datagram send state transition is : "
+ mShowDatagramSendStateTransition);
}
private void showDatagramReceiveStateTransitionApp(View view) {
TextView textView = findViewById(R.id.text_id);
textView.setText("Last datagram receive state transition is : "
+ mShowDatagramReceiveStateTransition);
}
private void registerForSatelliteModemStateChangedApp(View view) {
int result = mSatelliteManager.registerForSatelliteModemStateChanged(Runnable::run,
mStateCallback);
TextView textView = findViewById(R.id.text_id);
if (result == 0) {
textView.setText("registerForSatelliteModemStateChanged is successful");
} else {
textView.setText("Status for registerForSatelliteModemStateChanged : "
+ SatelliteErrorUtils.mapError(result));
}
}
private void unregisterForSatelliteModemStateChangedApp(View view) {
mSatelliteManager.unregisterForSatelliteModemStateChanged(mStateCallback);
TextView textView = findViewById(R.id.text_id);
textView.setText("unregisterForSatelliteModemStateChanged is successful");
}
private void showSatelliteModemStateTransitionApp(View view) {
TextView textView = findViewById(R.id.text_id);
textView.setText(
"Last modem transition state is: " + mShowSatelliteModemStateTransition);
}
private String getSatelliteModemStateName(@SatelliteManager.SatelliteModemState int state) {
switch (state) {
case SatelliteManager.SATELLITE_MODEM_STATE_IDLE:
return "IDLE";
case SatelliteManager.SATELLITE_MODEM_STATE_LISTENING:
return "LISTENING";
case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING:
return "DATAGRAM_TRANSFERRING";
case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING:
return "DATAGRAM_RETRYING";
case SatelliteManager.SATELLITE_MODEM_STATE_OFF:
return "OFF";
case SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE:
return "UNAVAILABLE";
default: return "UNKNOWN";
}
}
private String getSatelliteModemStateTransition(LinkedList<Integer> states) {
StringBuilder sb = new StringBuilder();
for (int state : states) {
sb.append(getSatelliteModemStateName(state));
sb.append("=>");
}
if (!sb.isEmpty()) {
sb.delete(sb.length() - 2, sb.length());
}
return sb.toString();
}
private String getDatagramTransferStateName(
@SatelliteManager.SatelliteDatagramTransferState int state) {
switch (state) {
case SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE: return "IDLE";
case SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING: return "SENDING";
case SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS: return "SEND_SUCCESS";
case SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED: return "SEND_FAILED";
case SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING: return "RECEIVING";
case SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS: return "RECEIVE_SUCCESS";
case SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE: return "RECEIVE_NONE";
case SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED: return "RECEIVE_FAILED";
default: return "UNKNOWN";
}
}
private String getTransferStateTransition(LinkedList<Integer> states) {
StringBuilder sb = new StringBuilder();
for (int state : states) {
sb.append(getDatagramTransferStateName(state));
sb.append("=>");
}
if (!sb.isEmpty()) {
sb.delete(sb.length() - 2, sb.length());
}
return sb.toString();
}
@Override
protected void onResume() {
super.onResume();
SharedPreferences sh = getSharedPreferences("TestSatelliteSharedPref", MODE_PRIVATE);
String modemStateTransition = sh.getString("modem_state",
mShowSatelliteModemStateTransition);
String datagramSendStateTransition = sh.getString("datagram_send_state",
mShowDatagramSendStateTransition);
String datagramReceiveStateTransition = sh.getString("datagram_receive_state",
mShowDatagramReceiveStateTransition);
// Setting the fetched data
mShowSatelliteModemStateTransition = modemStateTransition;
mShowDatagramSendStateTransition = datagramSendStateTransition;
mShowDatagramReceiveStateTransition = datagramReceiveStateTransition;
}
@Override
protected void onPause() {
super.onPause();
SharedPreferences sharedPreferences = getSharedPreferences("TestSatelliteSharedPref",
MODE_PRIVATE);
SharedPreferences.Editor myEdit = sharedPreferences.edit();
myEdit.putString("modem_state", mShowSatelliteModemStateTransition);
myEdit.putString("datagram_send_state", mShowDatagramSendStateTransition);
myEdit.putString("datagram_receive_state", mShowDatagramReceiveStateTransition);
myEdit.apply();
}
protected void onDestroy() {
super.onDestroy();
SharedPreferences sharedPreferences = getSharedPreferences("TestSatelliteSharedPref",
MODE_PRIVATE);
final SharedPreferences.Editor sharedPrefsEditor = sharedPreferences.edit();
sharedPrefsEditor.remove("modem_state");
sharedPrefsEditor.remove("datagram_send_state");
sharedPrefsEditor.remove("datagram_receive_state");
sharedPrefsEditor.commit();
}
}