blob: 2fc5e08e195fd6b3073fea488ca851978bbdf69e [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 android.telephony.cts;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeNoException;
import static org.junit.Assume.assumeTrue;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.OutcomeReceiver;
import android.telephony.TelephonyManager;
import android.telephony.satellite.PointingInfo;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteDatagramCallback;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteProvisionStateCallback;
import android.telephony.satellite.SatelliteStateCallback;
import android.telephony.satellite.SatelliteTransmissionUpdateCallback;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import com.android.internal.telephony.ILongConsumer;
import org.junit.Before;
import org.junit.Test;
import java.time.Duration;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
public class SatelliteManagerTest {
private static final String TAG = "SatelliteManagerTest";
private static final long TIMEOUT = 1000;
private SatelliteManager mSatelliteManager;
@Before
public void setUp() throws Exception {
assumeTrue(getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TELEPHONY_SATELLITE));
try {
getContext().getSystemService(TelephonyManager.class)
.getHalVersion(TelephonyManager.HAL_SERVICE_RADIO);
} catch (IllegalStateException e) {
assumeNoException("Skipping tests because Telephony service is null", e);
}
mSatelliteManager = getContext().getSystemService(SatelliteManager.class);
}
@Test
public void testSatelliteTransmissionUpdates() throws Exception {
LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
SatelliteTransmissionUpdateCallbackTest callback =
new SatelliteTransmissionUpdateCallbackTest();
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class,
() -> mSatelliteManager.startSatelliteTransmissionUpdates(
getContext().getMainExecutor(), error::offer, callback));
grantSatellitePermission();
int errorCode;
mSatelliteManager.startSatelliteTransmissionUpdates(
getContext().getMainExecutor(), error::offer, callback);
errorCode = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
if (errorCode == SatelliteManager.SATELLITE_ERROR_NONE) {
Log.d(TAG, "Successfully started transmission updates.");
} else {
Log.d(TAG, "Failed to start transmission updates: " + errorCode);
}
getContext().getSystemService(SatelliteManager.class).stopSatelliteTransmissionUpdates(
callback, getContext().getMainExecutor(), error::offer);
errorCode = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
Log.d(TAG, "Stop transmission updates: " + errorCode);
mSatelliteManager.stopSatelliteTransmissionUpdates(
callback, getContext().getMainExecutor(), error::offer);
errorCode = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
assertEquals(errorCode, SatelliteManager.SATELLITE_INVALID_ARGUMENTS);
revokeSatellitePermission();
}
@Test
public void testProvisionSatelliteService() {
LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class,
() -> mSatelliteManager.provisionSatelliteService(
"", "", null, getContext().getMainExecutor(), error::offer));
}
@Test
public void testDeprovisionSatelliteService() {
LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class,
() -> mSatelliteManager.deprovisionSatelliteService(
"", getContext().getMainExecutor(), error::offer));
}
@Test
public void testRegisterForSatelliteProvisionStateChanged() {
SatelliteProvisionStateCallbackTest satelliteProvisionStateCallback =
new SatelliteProvisionStateCallbackTest();
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class,
() -> mSatelliteManager.registerForSatelliteProvisionStateChanged(
getContext().getMainExecutor(), satelliteProvisionStateCallback));
}
@Test
public void testRequestIsSatelliteProvisioned() {
final AtomicReference<Boolean> provisioned = new AtomicReference<>();
final AtomicReference<Integer> errorCode = new AtomicReference<>();
OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> receiver =
new OutcomeReceiver<>() {
@Override
public void onResult(Boolean result) {
provisioned.set(result);
}
@Override
public void onError(SatelliteManager.SatelliteException exception) {
errorCode.set(exception.getErrorCode());
}
};
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class,
() -> mSatelliteManager.requestIsSatelliteProvisioned(
getContext().getMainExecutor(), receiver));
}
@Test
public void testRequestSatelliteEnabled() {
LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class, () -> mSatelliteManager.requestSatelliteEnabled(
true, true, getContext().getMainExecutor(), error::offer));
assertThrows(SecurityException.class, () -> mSatelliteManager.requestSatelliteEnabled(
false, true, getContext().getMainExecutor(), error::offer));
}
@Test
public void testRequestIsSatelliteEnabled() {
final AtomicReference<Boolean> enabled = new AtomicReference<>();
final AtomicReference<Integer> errorCode = new AtomicReference<>();
OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> receiver =
new OutcomeReceiver<>() {
@Override
public void onResult(Boolean result) {
enabled.set(result);
}
@Override
public void onError(SatelliteManager.SatelliteException exception) {
errorCode.set(exception.getErrorCode());
}
};
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class, () -> mSatelliteManager.requestIsSatelliteEnabled(
getContext().getMainExecutor(), receiver));
}
@Test
public void testRequestIsSatelliteSupported() throws Exception {
final AtomicReference<Boolean> supported = new AtomicReference<>();
final AtomicReference<Integer> errorCode = new AtomicReference<>();
CountDownLatch latch = new CountDownLatch(1);
OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> receiver =
new OutcomeReceiver<>() {
@Override
public void onResult(Boolean result) {
supported.set(result);
latch.countDown();
}
@Override
public void onError(SatelliteManager.SatelliteException exception) {
errorCode.set(exception.getErrorCode());
latch.countDown();
}
};
mSatelliteManager.requestIsSatelliteSupported(getContext().getMainExecutor(),
receiver);
assertTrue(latch.await(TIMEOUT, TimeUnit.MILLISECONDS));
assertNotNull(errorCode.get());
int error = errorCode.get();
if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
assertNotNull(supported.get());
} else {
assertNull(supported.get());
}
}
@Test
public void testRequestSatelliteCapabilities() {
final AtomicReference<SatelliteCapabilities> capabilities = new AtomicReference<>();
final AtomicReference<Integer> errorCode = new AtomicReference<>();
OutcomeReceiver<SatelliteCapabilities, SatelliteManager.SatelliteException> receiver =
new OutcomeReceiver<>() {
@Override
public void onResult(SatelliteCapabilities result) {
capabilities.set(result);
}
@Override
public void onError(SatelliteManager.SatelliteException exception) {
errorCode.set(exception.getErrorCode());
}
};
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class, () -> mSatelliteManager.requestSatelliteCapabilities(
getContext().getMainExecutor(), receiver));
}
@Test
public void testSatelliteModemStateChanged() throws Exception {
SatelliteStateCallbackTest callback = new SatelliteStateCallbackTest();
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class, ()-> mSatelliteManager
.registerForSatelliteModemStateChanged(getContext().getMainExecutor(), callback));
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class, ()-> mSatelliteManager
.unregisterForSatelliteModemStateChanged(callback));
}
@Test
public void testSatelliteDatagramCallback() throws Exception {
SatelliteDatagramCallbackTest callback = new SatelliteDatagramCallbackTest();
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class, ()-> mSatelliteManager
.registerForSatelliteDatagram(getContext().getMainExecutor(), callback));
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class, ()-> mSatelliteManager
.unregisterForSatelliteDatagram(callback));
}
@Test
public void testPollPendingSatelliteDatagrams() throws Exception {
LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class,
()-> mSatelliteManager.pollPendingSatelliteDatagrams(
getContext().getMainExecutor(), resultListener::offer));
}
@Test
public void testSendSatelliteDatagram() {
LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
String mText = "This is a test datagram message";
SatelliteDatagram datagram = new SatelliteDatagram(mText.getBytes());
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class,
()-> mSatelliteManager.sendSatelliteDatagram(
SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE, datagram, true,
getContext().getMainExecutor(), resultListener::offer));
// TODO: add detailed test
}
@Test
public void testRequestIsSatelliteCommunicationAllowedForCurrentLocation() {
final AtomicReference<Boolean> enabled = new AtomicReference<>();
final AtomicReference<Integer> errorCode = new AtomicReference<>();
OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> receiver =
new OutcomeReceiver<>() {
@Override
public void onResult(Boolean result) {
enabled.set(result);
}
@Override
public void onError(SatelliteManager.SatelliteException exception) {
errorCode.set(exception.getErrorCode());
}
};
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class, () -> mSatelliteManager.requestIsSatelliteEnabled(
getContext().getMainExecutor(), receiver));
}
@Test
public void testRequestTimeForNextSatelliteVisibility() {
final AtomicReference<Duration> nextVisibilityDuration = new AtomicReference<>();
final AtomicReference<Integer> errorCode = new AtomicReference<>();
OutcomeReceiver<Duration, SatelliteManager.SatelliteException> receiver =
new OutcomeReceiver<>() {
@Override
public void onResult(Duration result) {
nextVisibilityDuration.set(result);
}
@Override
public void onError(SatelliteManager.SatelliteException exception) {
errorCode.set(exception.getErrorCode());
}
};
// Throws SecurityException as we do not have SATELLITE_COMMUNICATION permission.
assertThrows(SecurityException.class,
() -> mSatelliteManager.requestTimeForNextSatelliteVisibility(
getContext().getMainExecutor(), receiver));
}
private Context getContext() {
return InstrumentationRegistry.getContext();
}
private void grantSatellitePermission() {
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.adoptShellPermissionIdentity(Manifest.permission.SATELLITE_COMMUNICATION);
}
private void revokeSatellitePermission() {
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.dropShellPermissionIdentity();
}
private static class SatelliteTransmissionUpdateCallbackTest implements
SatelliteTransmissionUpdateCallback {
@Override
public void onSatellitePositionChanged(PointingInfo pointingInfo) {
Log.d(TAG, "onSatellitePositionChanged: pointingInfo=" + pointingInfo);
}
@Override
public void onSendDatagramStateChanged(int state, int sendPendingCount, int errorCode) {
Log.d(TAG, "onSendDatagramStateChanged: state=" + state + ", sendPendingCount="
+ sendPendingCount + ", errorCode=" + errorCode);
}
@Override
public void onReceiveDatagramStateChanged(int state, int receivePendingCount, int errorCode) {
Log.d(TAG, "onReceiveDatagramStateChanged: state=" + state + ", "
+ "receivePendingCount=" + receivePendingCount + ", errorCode=" + errorCode);
}
}
private static class SatelliteProvisionStateCallbackTest implements
SatelliteProvisionStateCallback {
@Override
public void onSatelliteProvisionStateChanged(boolean provisioned) {
Log.d(TAG, "onSatelliteProvisionStateChanged: provisioned=" + provisioned);
}
}
private static class SatelliteStateCallbackTest implements SatelliteStateCallback {
@Override
public void onSatelliteModemStateChanged(int state) {
Log.d(TAG, "onSatelliteModemStateChanged: state=" + state);
}
}
private static class SatelliteDatagramCallbackTest implements SatelliteDatagramCallback {
@Override
public void onSatelliteDatagramReceived(long datagramId, SatelliteDatagram datagram,
int pendingCount, ILongConsumer callback) {
Log.d(TAG, "onSatelliteDatagramReceived: datagramId=" + datagramId + ", datagram="
+ datagram + ", pendingCount=" + pendingCount);
}
}
}