[ID] Replace "forensic" with "intrusion detection"
Improve terminology: Use "intrusion detection" instead of "forensic"
for accuracy
Bug: 365994454
Test: atest IntrusionDetectionServiceTest
Test: atest IntrusionDetectionManagerTest
Flag: android.security.afl_api
Ignore-AOSP-First: security feature
Change-Id: Ib60db2d91ef8b0a40605fc43fec7df32bb15c806
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 14a6c8c..f6f0ffb 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -66,10 +66,10 @@
field @FlaggedApi("android.crashrecovery.flags.enable_crashrecovery") public static final String BIND_EXPLICIT_HEALTH_CHECK_SERVICE = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
field public static final String BIND_EXTERNAL_STORAGE_SERVICE = "android.permission.BIND_EXTERNAL_STORAGE_SERVICE";
field public static final String BIND_FIELD_CLASSIFICATION_SERVICE = "android.permission.BIND_FIELD_CLASSIFICATION_SERVICE";
- field @FlaggedApi("android.security.afl_api") public static final String BIND_FORENSIC_EVENT_TRANSPORT_SERVICE = "android.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE";
field public static final String BIND_GBA_SERVICE = "android.permission.BIND_GBA_SERVICE";
field public static final String BIND_HOTWORD_DETECTION_SERVICE = "android.permission.BIND_HOTWORD_DETECTION_SERVICE";
field public static final String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
+ field @FlaggedApi("android.security.afl_api") public static final String BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE = "android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE";
field public static final String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
field public static final String BIND_MUSIC_RECOGNITION_SERVICE = "android.permission.BIND_MUSIC_RECOGNITION_SERVICE";
field public static final String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE";
@@ -213,12 +213,12 @@
field @FlaggedApi("android.permission.flags.enhanced_confirmation_mode_apis_enabled") public static final String MANAGE_ENHANCED_CONFIRMATION_STATES = "android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES";
field public static final String MANAGE_ETHERNET_NETWORKS = "android.permission.MANAGE_ETHERNET_NETWORKS";
field public static final String MANAGE_FACTORY_RESET_PROTECTION = "android.permission.MANAGE_FACTORY_RESET_PROTECTION";
- field @FlaggedApi("android.security.afl_api") public static final String MANAGE_FORENSIC_STATE = "android.permission.MANAGE_FORENSIC_STATE";
field public static final String MANAGE_GAME_ACTIVITY = "android.permission.MANAGE_GAME_ACTIVITY";
field public static final String MANAGE_GAME_MODE = "android.permission.MANAGE_GAME_MODE";
field @FlaggedApi("android.media.tv.flags.media_quality_fw") public static final String MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE = "android.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE";
field @FlaggedApi("android.media.tv.flags.media_quality_fw") public static final String MANAGE_GLOBAL_SOUND_QUALITY_SERVICE = "android.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE";
field public static final String MANAGE_HOTWORD_DETECTION = "android.permission.MANAGE_HOTWORD_DETECTION";
+ field @FlaggedApi("android.security.afl_api") public static final String MANAGE_INTRUSION_DETECTION_STATE = "android.permission.MANAGE_INTRUSION_DETECTION_STATE";
field public static final String MANAGE_IPSEC_TUNNELS = "android.permission.MANAGE_IPSEC_TUNNELS";
field public static final String MANAGE_LOW_POWER_STANDBY = "android.permission.MANAGE_LOW_POWER_STANDBY";
field public static final String MANAGE_MUSIC_RECOGNITION = "android.permission.MANAGE_MUSIC_RECOGNITION";
@@ -310,10 +310,10 @@
field public static final String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
field public static final String READ_DEVICE_CONFIG = "android.permission.READ_DEVICE_CONFIG";
field public static final String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE";
- field @FlaggedApi("android.security.afl_api") public static final String READ_FORENSIC_STATE = "android.permission.READ_FORENSIC_STATE";
field public static final String READ_GLOBAL_APP_SEARCH_DATA = "android.permission.READ_GLOBAL_APP_SEARCH_DATA";
field @FlaggedApi("android.content.pm.get_resolved_apk_path") public static final String READ_INSTALLED_SESSION_PATHS = "android.permission.READ_INSTALLED_SESSION_PATHS";
field public static final String READ_INSTALL_SESSIONS = "android.permission.READ_INSTALL_SESSIONS";
+ field @FlaggedApi("android.security.afl_api") public static final String READ_INTRUSION_DETECTION_STATE = "android.permission.READ_INTRUSION_DETECTION_STATE";
field public static final String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY";
field public static final String READ_OEM_UNLOCK_STATE = "android.permission.READ_OEM_UNLOCK_STATE";
field public static final String READ_PEOPLE_DATA = "android.permission.READ_PEOPLE_DATA";
@@ -12891,13 +12891,13 @@
}
-package android.security.forensic {
+package android.security.intrusiondetection {
- @FlaggedApi("android.security.afl_api") public class ForensicManager {
- method @RequiresPermission(android.Manifest.permission.READ_FORENSIC_STATE) public void addStateCallback(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @RequiresPermission(android.Manifest.permission.MANAGE_FORENSIC_STATE) public void disable(@NonNull java.util.concurrent.Executor, @NonNull android.security.forensic.ForensicManager.CommandCallback);
- method @RequiresPermission(android.Manifest.permission.MANAGE_FORENSIC_STATE) public void enable(@NonNull java.util.concurrent.Executor, @NonNull android.security.forensic.ForensicManager.CommandCallback);
- method @RequiresPermission(android.Manifest.permission.READ_FORENSIC_STATE) public void removeStateCallback(@NonNull java.util.function.Consumer<java.lang.Integer>);
+ @FlaggedApi("android.security.afl_api") public class IntrusionDetectionManager {
+ method @RequiresPermission(android.Manifest.permission.READ_INTRUSION_DETECTION_STATE) public void addStateCallback(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE) public void disable(@NonNull java.util.concurrent.Executor, @NonNull android.security.intrusiondetection.IntrusionDetectionManager.CommandCallback);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE) public void enable(@NonNull java.util.concurrent.Executor, @NonNull android.security.intrusiondetection.IntrusionDetectionManager.CommandCallback);
+ method @RequiresPermission(android.Manifest.permission.READ_INTRUSION_DETECTION_STATE) public void removeStateCallback(@NonNull java.util.function.Consumer<java.lang.Integer>);
field public static final int ERROR_DATA_SOURCE_UNAVAILABLE = 4; // 0x4
field public static final int ERROR_PERMISSION_DENIED = 1; // 0x1
field public static final int ERROR_TRANSPORT_UNAVAILABLE = 3; // 0x3
@@ -12907,7 +12907,7 @@
field public static final int STATE_UNKNOWN = 0; // 0x0
}
- public static interface ForensicManager.CommandCallback {
+ public static interface IntrusionDetectionManager.CommandCallback {
method public void onFailure(int);
method public void onSuccess();
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 6a23349..2bd2d34 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -243,8 +243,8 @@
import android.security.attestationverification.IAttestationVerificationManagerService;
import android.security.authenticationpolicy.AuthenticationPolicyManager;
import android.security.authenticationpolicy.IAuthenticationPolicyService;
-import android.security.forensic.ForensicManager;
-import android.security.forensic.IForensicService;
+import android.security.intrusiondetection.IIntrusionDetectionService;
+import android.security.intrusiondetection.IntrusionDetectionManager;
import android.security.keystore.KeyStoreManager;
import android.service.oemlock.IOemLockService;
import android.service.oemlock.OemLockManager;
@@ -1818,15 +1818,20 @@
}
});
- registerService(Context.FORENSIC_SERVICE, ForensicManager.class,
- new CachedServiceFetcher<ForensicManager>() {
+ registerService(Context.INTRUSION_DETECTION_SERVICE, IntrusionDetectionManager.class,
+ new CachedServiceFetcher<IntrusionDetectionManager>() {
@Override
- public ForensicManager createService(ContextImpl ctx)
+ public IntrusionDetectionManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
+ if (!android.security.Flags.aflApi()) {
+ throw new ServiceNotFoundException(
+ "Intrusion Detection is not supported");
+ }
IBinder b = ServiceManager.getServiceOrThrow(
- Context.FORENSIC_SERVICE);
- IForensicService service = IForensicService.Stub.asInterface(b);
- return new ForensicManager(service);
+ Context.INTRUSION_DETECTION_SERVICE);
+ IIntrusionDetectionService service =
+ IIntrusionDetectionService.Stub.asInterface(b);
+ return new IntrusionDetectionManager(service);
}
});
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 19cd2e6..acad92c9 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5713,12 +5713,12 @@
public static final String BINARY_TRANSPARENCY_SERVICE = "transparency";
/**
- * System service name for ForensicService.
- * The service manages the forensic info on device.
+ * System service name for IntrusionDetectionService.
+ * The service manages the intrusion detection info on device.
* @hide
*/
@FlaggedApi(android.security.Flags.FLAG_AFL_API)
- public static final String FORENSIC_SERVICE = "forensic";
+ public static final String INTRUSION_DETECTION_SERVICE = "intrusion_detection";
/**
* System service name for the DeviceIdleManager.
diff --git a/core/java/android/security/forensic/IForensicService.aidl b/core/java/android/security/forensic/IForensicService.aidl
deleted file mode 100644
index 8039b26..0000000
--- a/core/java/android/security/forensic/IForensicService.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2024 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.security.forensic;
-
-import android.security.forensic.IForensicServiceCommandCallback;
-import android.security.forensic.IForensicServiceStateCallback;
-
-/**
- * Binder interface to communicate with ForensicService.
- * @hide
- */
-interface IForensicService {
- @EnforcePermission("READ_FORENSIC_STATE")
- void addStateCallback(IForensicServiceStateCallback callback);
- @EnforcePermission("READ_FORENSIC_STATE")
- void removeStateCallback(IForensicServiceStateCallback callback);
- @EnforcePermission("MANAGE_FORENSIC_STATE")
- void enable(IForensicServiceCommandCallback callback);
- @EnforcePermission("MANAGE_FORENSIC_STATE")
- void disable(IForensicServiceCommandCallback callback);
-}
diff --git a/core/java/android/security/forensic/IForensicEventTransport.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
similarity index 67%
rename from core/java/android/security/forensic/IForensicEventTransport.aidl
rename to core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
index 80e78eb..8759f72 100644
--- a/core/java/android/security/forensic/IForensicEventTransport.aidl
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
@@ -14,25 +14,25 @@
* limitations under the License.
*/
-package android.security.forensic;
-import android.security.forensic.ForensicEvent;
+package android.security.intrusiondetection;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import com.android.internal.infra.AndroidFuture;
/** {@hide} */
-oneway interface IForensicEventTransport {
+oneway interface IIntrusionDetectionEventTransport {
/**
* Initialize the server side.
*/
void initialize(in AndroidFuture<int> resultFuture);
/**
- * Send forensic logging data to the backup destination.
- * The data is a list of ForensicEvent.
- * The ForensicEvent is an abstract class that represents
+ * Send intrusiondetection logging data to the backup destination.
+ * The data is a list of IntrusionDetectionEvent.
+ * The IntrusionDetectionEvent is an abstract class that represents
* different type of events.
*/
- void addData(in List<ForensicEvent> events, in AndroidFuture<int> resultFuture);
+ void addData(in List<IntrusionDetectionEvent> events, in AndroidFuture<int> resultFuture);
/**
* Release the binder to the server.
diff --git a/core/java/android/security/intrusiondetection/IIntrusionDetectionService.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionService.aidl
new file mode 100644
index 0000000..0ba9418
--- /dev/null
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionService.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2024 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.security.intrusiondetection;
+
+import android.security.intrusiondetection.IIntrusionDetectionServiceCommandCallback;
+import android.security.intrusiondetection.IIntrusionDetectionServiceStateCallback;
+
+/**
+ * Binder interface to communicate with IntrusionDetectionService.
+ * @hide
+ */
+interface IIntrusionDetectionService {
+ @EnforcePermission("READ_INTRUSION_DETECTION_STATE")
+ void addStateCallback(IIntrusionDetectionServiceStateCallback callback);
+ @EnforcePermission("READ_INTRUSION_DETECTION_STATE")
+ void removeStateCallback(IIntrusionDetectionServiceStateCallback callback);
+ @EnforcePermission("MANAGE_INTRUSION_DETECTION_STATE")
+ void enable(IIntrusionDetectionServiceCommandCallback callback);
+ @EnforcePermission("MANAGE_INTRUSION_DETECTION_STATE")
+ void disable(IIntrusionDetectionServiceCommandCallback callback);
+}
diff --git a/core/java/android/security/forensic/IForensicServiceCommandCallback.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionServiceCommandCallback.aidl
similarity index 89%
rename from core/java/android/security/forensic/IForensicServiceCommandCallback.aidl
rename to core/java/android/security/intrusiondetection/IIntrusionDetectionServiceCommandCallback.aidl
index 6d1456e..80f09d5 100644
--- a/core/java/android/security/forensic/IForensicServiceCommandCallback.aidl
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionServiceCommandCallback.aidl
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
/**
* @hide
*/
- oneway interface IForensicServiceCommandCallback {
+ oneway interface IIntrusionDetectionServiceCommandCallback {
@Backing(type="int")
enum ErrorCode{
UNKNOWN = 0,
diff --git a/core/java/android/security/forensic/IForensicServiceStateCallback.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionServiceStateCallback.aidl
similarity index 87%
rename from core/java/android/security/forensic/IForensicServiceStateCallback.aidl
rename to core/java/android/security/intrusiondetection/IIntrusionDetectionServiceStateCallback.aidl
index 1b68c7b..c88dc21 100644
--- a/core/java/android/security/forensic/IForensicServiceStateCallback.aidl
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionServiceStateCallback.aidl
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
/**
* @hide
*/
- oneway interface IForensicServiceStateCallback {
+ oneway interface IIntrusionDetectionServiceStateCallback {
@Backing(type="int")
enum State{
UNKNOWN = 0,
diff --git a/core/java/android/security/forensic/ForensicEvent.aidl b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.aidl
similarity index 88%
rename from core/java/android/security/forensic/ForensicEvent.aidl
rename to core/java/android/security/intrusiondetection/IntrusionDetectionEvent.aidl
index a321fb0..80b4396 100644
--- a/core/java/android/security/forensic/ForensicEvent.aidl
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
/** {@hide} */
-parcelable ForensicEvent;
+parcelable IntrusionDetectionEvent;
diff --git a/core/java/android/security/forensic/ForensicEvent.java b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
similarity index 80%
rename from core/java/android/security/forensic/ForensicEvent.java
rename to core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
index 3d908cc..538acf9 100644
--- a/core/java/android/security/forensic/ForensicEvent.java
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
@@ -30,12 +30,12 @@
import java.lang.annotation.RetentionPolicy;
/**
- * A class that represents a forensic event.
+ * A class that represents a intrusiondetection event.
* @hide
*/
@FlaggedApi(Flags.FLAG_AFL_API)
-public final class ForensicEvent implements Parcelable {
- private static final String TAG = "ForensicEvent";
+public final class IntrusionDetectionEvent implements Parcelable {
+ private static final String TAG = "IntrusionDetectionEvent";
public static final int SECURITY_EVENT = 0;
public static final int NETWORK_EVENT_DNS = 1;
@@ -44,9 +44,9 @@
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
- ForensicEvent.SECURITY_EVENT,
- ForensicEvent.NETWORK_EVENT_DNS,
- ForensicEvent.NETWORK_EVENT_CONNECT,
+ IntrusionDetectionEvent.SECURITY_EVENT,
+ IntrusionDetectionEvent.NETWORK_EVENT_DNS,
+ IntrusionDetectionEvent.NETWORK_EVENT_CONNECT,
})
public @interface EventType {}
@@ -56,39 +56,39 @@
private final DnsEvent mNetworkEventDns;
private final ConnectEvent mNetworkEventConnect;
- public static final @NonNull Parcelable.Creator<ForensicEvent> CREATOR =
+ public static final @NonNull Parcelable.Creator<IntrusionDetectionEvent> CREATOR =
new Parcelable.Creator<>() {
- public ForensicEvent createFromParcel(Parcel in) {
- return new ForensicEvent(in);
+ public IntrusionDetectionEvent createFromParcel(Parcel in) {
+ return new IntrusionDetectionEvent(in);
}
- public ForensicEvent[] newArray(int size) {
- return new ForensicEvent[size];
+ public IntrusionDetectionEvent[] newArray(int size) {
+ return new IntrusionDetectionEvent[size];
}
};
- public ForensicEvent(@NonNull SecurityEvent securityEvent) {
+ public IntrusionDetectionEvent(@NonNull SecurityEvent securityEvent) {
mType = SECURITY_EVENT;
mSecurityEvent = securityEvent;
mNetworkEventDns = null;
mNetworkEventConnect = null;
}
- public ForensicEvent(@NonNull DnsEvent dnsEvent) {
+ public IntrusionDetectionEvent(@NonNull DnsEvent dnsEvent) {
mType = NETWORK_EVENT_DNS;
mNetworkEventDns = dnsEvent;
mSecurityEvent = null;
mNetworkEventConnect = null;
}
- public ForensicEvent(@NonNull ConnectEvent connectEvent) {
+ public IntrusionDetectionEvent(@NonNull ConnectEvent connectEvent) {
mType = NETWORK_EVENT_CONNECT;
mNetworkEventConnect = connectEvent;
mSecurityEvent = null;
mNetworkEventDns = null;
}
- private ForensicEvent(@NonNull Parcel in) {
+ private IntrusionDetectionEvent(@NonNull Parcel in) {
mType = in.readInt();
switch (mType) {
case SECURITY_EVENT:
@@ -111,7 +111,7 @@
}
}
- /** Returns the type of the forensic event. */
+ /** Returns the type of the IntrusionDetectionEvent. */
@NonNull
public @EventType int getType() {
return mType;
@@ -170,7 +170,7 @@
@Override
public String toString() {
- return "ForensicEvent{"
+ return "IntrusionDetectionEvent{"
+ "mType=" + mType
+ '}';
}
diff --git a/core/java/android/security/forensic/ForensicManager.java b/core/java/android/security/intrusiondetection/IntrusionDetectionManager.java
similarity index 62%
rename from core/java/android/security/forensic/ForensicManager.java
rename to core/java/android/security/intrusiondetection/IntrusionDetectionManager.java
index 9126182..e246338 100644
--- a/core/java/android/security/forensic/ForensicManager.java
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionManager.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
-import static android.Manifest.permission.MANAGE_FORENSIC_STATE;
-import static android.Manifest.permission.READ_FORENSIC_STATE;
+import static android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE;
+import static android.Manifest.permission.READ_INTRUSION_DETECTION_STATE;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
@@ -41,23 +41,23 @@
import java.util.function.Consumer;
/**
- * ForensicManager manages the forensic logging on Android devices.
- * Upon user consent, forensic logging collects various device events for
+ * IntrusionDetectionManager manages the intrusion detection on Android devices.
+ * Upon user consent, intrusion detection collects various device events for
* off-device investigation of potential device compromise.
* <p>
- * Forensic logging can either be enabled ({@link #STATE_ENABLED}
+ * Intrusion detection logging can either be enabled ({@link #STATE_ENABLED}
* or disabled ({@link #STATE_DISABLED}).
* <p>
- * The Forensic logs will be transferred to
- * {@link android.security.forensic.ForensicEventTransport}.
+ * The intrusion detection logs will be transferred to
+ * {@link android.security.intrusiondetection.IntrusionDetectionEventTransport}.
*
* @hide
*/
@SystemApi
@FlaggedApi(Flags.FLAG_AFL_API)
-@SystemService(Context.FORENSIC_SERVICE)
-public class ForensicManager {
- private static final String TAG = "ForensicManager";
+@SystemService(Context.INTRUSION_DETECTION_SERVICE)
+public class IntrusionDetectionManager {
+ private static final String TAG = "IntrusionDetectionManager";
/** @hide */
@Target(ElementType.TYPE_USE)
@@ -67,7 +67,7 @@
STATE_DISABLED,
STATE_ENABLED
})
- public @interface ForensicState {}
+ public @interface IntrusionDetectionState {}
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -77,64 +77,65 @@
ERROR_TRANSPORT_UNAVAILABLE,
ERROR_DATA_SOURCE_UNAVAILABLE
})
- public @interface ForensicError {}
+ public @interface IntrusionDetectionError {}
/**
* Indicates an unknown state
*/
- public static final int STATE_UNKNOWN = IForensicServiceStateCallback.State.UNKNOWN;
+ public static final int STATE_UNKNOWN = IIntrusionDetectionServiceStateCallback.State.UNKNOWN;
/**
- * Indicates an state that the forensic is turned off.
+ * Indicates an state that the intrusion detection is turned off.
*/
- public static final int STATE_DISABLED = IForensicServiceStateCallback.State.DISABLED;
+ public static final int STATE_DISABLED = IIntrusionDetectionServiceStateCallback.State.DISABLED;
/**
- * Indicates an state that the forensic is turned on.
+ * Indicates an state that the intrusion detection is turned on.
*/
- public static final int STATE_ENABLED = IForensicServiceStateCallback.State.ENABLED;
+ public static final int STATE_ENABLED = IIntrusionDetectionServiceStateCallback.State.ENABLED;
/**
* Indicates an unknown error
*/
- public static final int ERROR_UNKNOWN = IForensicServiceCommandCallback.ErrorCode.UNKNOWN;
+ public static final int ERROR_UNKNOWN =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.UNKNOWN;
/**
* Indicates an error due to insufficient access rights.
*/
public static final int ERROR_PERMISSION_DENIED =
- IForensicServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
/**
- * Indicates an error due to unavailability of the forensic event transport.
+ * Indicates an error due to unavailability of the intrusion detection event transport.
*/
public static final int ERROR_TRANSPORT_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
/**
* Indicates an error due to unavailability of the data source.
*/
public static final int ERROR_DATA_SOURCE_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
- private final IForensicService mService;
+ private final IIntrusionDetectionService mService;
- private final ConcurrentHashMap<Consumer<Integer>, IForensicServiceStateCallback>
+ private final ConcurrentHashMap<Consumer<Integer>, IIntrusionDetectionServiceStateCallback>
mStateCallbacks = new ConcurrentHashMap<>();
/**
* Constructor
*
- * @param service A valid instance of IForensicService.
+ * @param service A valid instance of IIntrusionDetectionService.
* @hide
*/
- public ForensicManager(IForensicService service) {
+ public IntrusionDetectionManager(IIntrusionDetectionService service) {
mService = service;
}
/**
- * Add a callback to monitor the state of the ForensicService.
+ * Add a callback to monitor the state of the IntrusionDetectionService.
*
* @param executor The executor through which the callback should be invoked.
* @param callback The callback for state change.
@@ -142,9 +143,9 @@
* to reflect the init state.
* The callback can be registered only once.
*/
- @RequiresPermission(READ_FORENSIC_STATE)
+ @RequiresPermission(READ_INTRUSION_DETECTION_STATE)
public void addStateCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull @ForensicState Consumer<Integer> callback) {
+ @NonNull @IntrusionDetectionState Consumer<Integer> callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
@@ -153,8 +154,8 @@
return;
}
- final IForensicServiceStateCallback wrappedCallback =
- new IForensicServiceStateCallback.Stub() {
+ final IIntrusionDetectionServiceStateCallback wrappedCallback =
+ new IIntrusionDetectionServiceStateCallback.Stub() {
@Override
public void onStateChange(int state) {
executor.execute(() -> callback.accept(state));
@@ -170,19 +171,19 @@
}
/**
- * Remove a callback to monitor the state of the ForensicService.
+ * Remove a callback to monitor the state of the IntrusionDetectionService.
*
* @param callback The callback to remove.
*/
- @RequiresPermission(READ_FORENSIC_STATE)
- public void removeStateCallback(@NonNull Consumer<@ForensicState Integer> callback) {
+ @RequiresPermission(READ_INTRUSION_DETECTION_STATE)
+ public void removeStateCallback(@NonNull Consumer<@IntrusionDetectionState Integer> callback) {
Objects.requireNonNull(callback);
if (!mStateCallbacks.containsKey(callback)) {
Log.d(TAG, "removeStateCallback callback not present");
return;
}
- IForensicServiceStateCallback wrappedCallback = mStateCallbacks.get(callback);
+ IIntrusionDetectionServiceStateCallback wrappedCallback = mStateCallbacks.get(callback);
try {
mService.removeStateCallback(wrappedCallback);
@@ -194,22 +195,23 @@
}
/**
- * Enable forensic logging.
- * If successful, ForensicService will transition to {@link #STATE_ENABLED} state.
+ * Enable intrusion detection.
+ * If successful, IntrusionDetectionService will transition to {@link #STATE_ENABLED} state.
* <p>
- * When forensic logging is enabled, various device events will be collected and
- * sent over to the registered {@link android.security.forensic.ForensicEventTransport}.
+ * When intrusion detection is enabled, various device events will be collected and
+ * sent over to the registered
+ * {@link android.security.intrusiondetection.IntrusionDetectionEventTransport}.
*
* @param executor The executor through which the callback should be invoked.
* @param callback The callback for the command result.
*/
- @RequiresPermission(MANAGE_FORENSIC_STATE)
+ @RequiresPermission(MANAGE_INTRUSION_DETECTION_STATE)
public void enable(@NonNull @CallbackExecutor Executor executor,
@NonNull CommandCallback callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
try {
- mService.enable(new IForensicServiceCommandCallback.Stub() {
+ mService.enable(new IIntrusionDetectionServiceCommandCallback.Stub() {
@Override
public void onSuccess() {
executor.execute(callback::onSuccess);
@@ -226,23 +228,23 @@
}
/**
- * Disable forensic logging.
- * If successful, ForensicService will transition to {@link #STATE_DISABLED}.
+ * Disable intrusion detection.
+ * If successful, IntrusionDetectionService will transition to {@link #STATE_DISABLED}.
* <p>
- * When forensic logging is disabled, device events will no longer be collected.
- * Any events that have been collected but not yet sent to ForensicEventTransport
+ * When intrusion detection is disabled, device events will no longer be collected.
+ * Any events that have been collected but not yet sent to IntrusionDetectionEventTransport
* will be transferred as a final batch.
*
* @param executor The executor through which the callback should be invoked.
* @param callback The callback for the command result.
*/
- @RequiresPermission(MANAGE_FORENSIC_STATE)
+ @RequiresPermission(MANAGE_INTRUSION_DETECTION_STATE)
public void disable(@NonNull @CallbackExecutor Executor executor,
@NonNull CommandCallback callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
try {
- mService.disable(new IForensicServiceCommandCallback.Stub() {
+ mService.disable(new IIntrusionDetectionServiceCommandCallback.Stub() {
@Override
public void onSuccess() {
executor.execute(callback::onSuccess);
@@ -271,6 +273,6 @@
* Called when command fails.
* @param error The error number.
*/
- void onFailure(@ForensicError int error);
+ void onFailure(@IntrusionDetectionError int error);
}
}
diff --git a/core/java/android/security/forensic/OWNERS b/core/java/android/security/intrusiondetection/OWNERS
similarity index 100%
rename from core/java/android/security/forensic/OWNERS
rename to core/java/android/security/intrusiondetection/OWNERS
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8cc7b0b..cd05a67 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4203,35 +4203,35 @@
<uses-permission android:name="android.permission.QUERY_ADVANCED_PROTECTION_MODE"
android:featureFlag="android.security.aapm_api"/>
- <!-- Allows an application to read the state of the ForensicService
+ <!-- Allows an application to read the state of the IntrusionDetectionService
@FlaggedApi(android.security.Flags.FLAG_AFL_API)
@SystemApi
@hide -->
- <permission android:name="android.permission.READ_FORENSIC_STATE"
+ <permission android:name="android.permission.READ_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"
android:protectionLevel="signature|privileged" />
- <uses-permission android:name="android.permission.READ_FORENSIC_STATE"
+ <uses-permission android:name="android.permission.READ_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"/>
- <!-- Allows an application to change the state of the ForensicService
+ <!-- Allows an application to change the state of the IntrusionDetectionService
@FlaggedApi(android.security.Flags.FLAG_AFL_API)
@SystemApi
@hide -->
- <permission android:name="android.permission.MANAGE_FORENSIC_STATE"
+ <permission android:name="android.permission.MANAGE_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"
android:protectionLevel="signature|privileged" />
- <uses-permission android:name="android.permission.MANAGE_FORENSIC_STATE"
+ <uses-permission android:name="android.permission.MANAGE_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"/>
- <!-- Must be required by any ForensicEventTransportService to ensure that
+ <!-- Must be required by any IntrusionDetectionEventTransportService to ensure that
only the system can bind to it.
@FlaggedApi(android.security.Flags.FLAG_AFL_API)
@SystemApi
@hide -->
- <permission android:name="android.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE"
+ <permission android:name="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE"
android:featureFlag="android.security.afl_api"
android:protectionLevel="signature" />
- <uses-permission android:name="android.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE"
+ <uses-permission android:name="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE"
android:featureFlag="android.security.afl_api"/>
<!-- @SystemApi @hide Allows an application to set a device owner on retail demo devices.-->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3f4ea2d..41fefb5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -7225,8 +7225,8 @@
<!-- Package for opening identity check settings page [CHAR LIMIT=NONE] [DO NOT TRANSLATE] -->
<string name="identity_check_settings_package_name">com\u002eandroid\u002esettings</string>
- <!-- The name of the service for forensic event transport. -->
- <string name="config_forensicEventTransport" translatable="false"></string>
+ <!-- The name of the service for intrusion detection event transport. -->
+ <string name="config_intrusionDetectionEventTransport" translatable="false"></string>
<!-- Whether to enable fp unlock when screen turns off on udfps devices -->
<bool name="config_screen_off_udfps_enabled">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5a6b66c..d3ccd07 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -5703,8 +5703,8 @@
<java-symbol type="string" name="identity_check_settings_action" />
<java-symbol type="string" name="identity_check_settings_package_name" />
- <!-- Forensic event transport -->
- <java-symbol type="string" name="config_forensicEventTransport" />
+ <!-- Intrusion detection event transport -->
+ <java-symbol type="string" name="config_intrusionDetectionEventTransport" />
<!-- Fingerprint screen off unlock config -->
<java-symbol type="bool" name="config_screen_off_udfps_enabled" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 329e5de..836870e 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -605,9 +605,9 @@
<!-- Permissions required for CTS test - SettingsPreferenceServiceClientTest -->
<permission name="android.permission.READ_SYSTEM_PREFERENCES" />
<permission name="android.permission.WRITE_SYSTEM_PREFERENCES" />
- <!-- Permission required for CTS test - ForensicManagerTest -->
- <permission name="android.permission.READ_FORENSIC_STATE" />
- <permission name="android.permission.MANAGE_FORENSIC_STATE" />
+ <!-- Permission required for CTS test - IntrusionDetectionManagerTest -->
+ <permission name="android.permission.READ_INTRUSION_DETECTION_STATE" />
+ <permission name="android.permission.MANAGE_INTRUSION_DETECTION_STATE" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 1070ebd..0df47ef 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -959,10 +959,10 @@
<uses-permission android:name="android.permission.QUERY_ADVANCED_PROTECTION_MODE"
android:featureFlag="android.security.aapm_api"/>
- <!-- Permission required for CTS test - ForensicManagerTest -->
- <uses-permission android:name="android.permission.READ_FORENSIC_STATE"
+ <!-- Permission required for CTS test - IntrusionDetectionManagerTest -->
+ <uses-permission android:name="android.permission.READ_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"/>
- <uses-permission android:name="android.permission.MANAGE_FORENSIC_STATE"
+ <uses-permission android:name="android.permission.MANAGE_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"/>
diff --git a/services/core/java/com/android/server/security/forensic/ForensicService.java b/services/core/java/com/android/server/security/forensic/ForensicService.java
deleted file mode 100644
index 2be068f..0000000
--- a/services/core/java/com/android/server/security/forensic/ForensicService.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2024 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.server.security.forensic;
-
-import static android.Manifest.permission.MANAGE_FORENSIC_STATE;
-import static android.Manifest.permission.READ_FORENSIC_STATE;
-
-import android.annotation.EnforcePermission;
-import android.annotation.NonNull;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PermissionEnforcer;
-import android.os.RemoteException;
-import android.security.forensic.ForensicEvent;
-import android.security.forensic.IForensicService;
-import android.security.forensic.IForensicServiceCommandCallback;
-import android.security.forensic.IForensicServiceStateCallback;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.ServiceThread;
-import com.android.server.SystemService;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @hide
- */
-public class ForensicService extends SystemService {
- private static final String TAG = "ForensicService";
-
- private static final int MAX_STATE_CALLBACK_NUM = 16;
- private static final int MSG_ADD_STATE_CALLBACK = 0;
- private static final int MSG_REMOVE_STATE_CALLBACK = 1;
- private static final int MSG_ENABLE = 2;
- private static final int MSG_DISABLE = 3;
- private static final int MSG_TRANSPORT = 4;
-
- private static final int STATE_UNKNOWN = IForensicServiceStateCallback.State.UNKNOWN;
- private static final int STATE_DISABLED = IForensicServiceStateCallback.State.DISABLED;
- private static final int STATE_ENABLED = IForensicServiceStateCallback.State.ENABLED;
-
- private static final int ERROR_UNKNOWN = IForensicServiceCommandCallback.ErrorCode.UNKNOWN;
- private static final int ERROR_PERMISSION_DENIED =
- IForensicServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
- private static final int ERROR_INVALID_STATE_TRANSITION =
- IForensicServiceCommandCallback.ErrorCode.INVALID_STATE_TRANSITION;
- private static final int ERROR_TRANSPORT_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
- private static final int ERROR_DATA_SOURCE_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
-
- private final Context mContext;
- private final Handler mHandler;
- private final ForensicEventTransportConnection mForensicEventTransportConnection;
- private final DataAggregator mDataAggregator;
- private final BinderService mBinderService;
-
- private final ArrayList<IForensicServiceStateCallback> mStateCallbacks = new ArrayList<>();
- private volatile int mState = STATE_DISABLED;
-
- public ForensicService(@NonNull Context context) {
- this(new InjectorImpl(context));
- }
-
- @VisibleForTesting
- ForensicService(@NonNull Injector injector) {
- super(injector.getContext());
- mContext = injector.getContext();
- mHandler = new EventHandler(injector.getLooper(), this);
- mForensicEventTransportConnection = injector.getForensicEventransportConnection();
- mDataAggregator = injector.getDataAggregator(this);
- mBinderService = new BinderService(this, injector.getPermissionEnforcer());
- }
-
- @VisibleForTesting
- protected void setState(int state) {
- mState = state;
- }
-
- private static final class BinderService extends IForensicService.Stub {
- final ForensicService mService;
-
- BinderService(ForensicService service, @NonNull PermissionEnforcer permissionEnforcer) {
- super(permissionEnforcer);
- mService = service;
- }
-
- @Override
- @EnforcePermission(READ_FORENSIC_STATE)
- public void addStateCallback(IForensicServiceStateCallback callback) {
- addStateCallback_enforcePermission();
- mService.mHandler.obtainMessage(MSG_ADD_STATE_CALLBACK, callback).sendToTarget();
- }
-
- @Override
- @EnforcePermission(READ_FORENSIC_STATE)
- public void removeStateCallback(IForensicServiceStateCallback callback) {
- removeStateCallback_enforcePermission();
- mService.mHandler.obtainMessage(MSG_REMOVE_STATE_CALLBACK, callback).sendToTarget();
- }
-
- @Override
- @EnforcePermission(MANAGE_FORENSIC_STATE)
- public void enable(IForensicServiceCommandCallback callback) {
- enable_enforcePermission();
- mService.mHandler.obtainMessage(MSG_ENABLE, callback).sendToTarget();
- }
-
- @Override
- @EnforcePermission(MANAGE_FORENSIC_STATE)
- public void disable(IForensicServiceCommandCallback callback) {
- disable_enforcePermission();
- mService.mHandler.obtainMessage(MSG_DISABLE, callback).sendToTarget();
- }
- }
-
- private static class EventHandler extends Handler {
- private final ForensicService mService;
-
- EventHandler(Looper looper, ForensicService service) {
- super(looper);
- mService = service;
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_ADD_STATE_CALLBACK:
- try {
- mService.addStateCallback(
- (IForensicServiceStateCallback) msg.obj);
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException", e);
- }
- break;
- case MSG_REMOVE_STATE_CALLBACK:
- try {
- mService.removeStateCallback(
- (IForensicServiceStateCallback) msg.obj);
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException", e);
- }
- break;
- case MSG_ENABLE:
- try {
- mService.enable((IForensicServiceCommandCallback) msg.obj);
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException", e);
- }
- break;
- case MSG_DISABLE:
- try {
- mService.disable((IForensicServiceCommandCallback) msg.obj);
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException", e);
- }
- break;
- case MSG_TRANSPORT:
- mService.transport((List<ForensicEvent>) msg.obj);
- break;
- default:
- Slog.w(TAG, "Unknown message: " + msg.what);
- }
- }
- }
-
- private void addStateCallback(IForensicServiceStateCallback callback) throws RemoteException {
- for (int i = 0; i < mStateCallbacks.size(); i++) {
- if (mStateCallbacks.get(i).asBinder() == callback.asBinder()) {
- return;
- }
- }
- mStateCallbacks.add(callback);
- callback.onStateChange(mState);
- }
-
- private void removeStateCallback(IForensicServiceStateCallback callback)
- throws RemoteException {
- for (int i = 0; i < mStateCallbacks.size(); i++) {
- if (mStateCallbacks.get(i).asBinder() == callback.asBinder()) {
- mStateCallbacks.remove(i);
- return;
- }
- }
- }
-
- private void notifyStateMonitors() {
- if (mStateCallbacks.size() >= MAX_STATE_CALLBACK_NUM) {
- mStateCallbacks.removeFirst();
- }
-
- for (int i = 0; i < mStateCallbacks.size(); i++) {
- try {
- mStateCallbacks.get(i).onStateChange(mState);
- } catch (RemoteException e) {
- mStateCallbacks.remove(i);
- }
- }
- }
-
- private void enable(IForensicServiceCommandCallback callback) throws RemoteException {
- if (mState == STATE_ENABLED) {
- callback.onSuccess();
- return;
- }
-
- // TODO: temporarily disable the following for the CTS ForensicManagerTest.
- // Enable it when the transport component is ready.
- // if (!mForensicEventTransportConnection.initialize()) {
- // callback.onFailure(ERROR_TRANSPORT_UNAVAILABLE);
- // return;
- // }
-
- mDataAggregator.enable();
- mState = STATE_ENABLED;
- notifyStateMonitors();
- callback.onSuccess();
- }
-
- private void disable(IForensicServiceCommandCallback callback) throws RemoteException {
- if (mState == STATE_DISABLED) {
- callback.onSuccess();
- return;
- }
-
- // TODO: temporarily disable the following for the CTS ForensicManagerTest.
- // Enable it when the transport component is ready.
- // mForensicEventTransportConnection.release();
- mDataAggregator.disable();
- mState = STATE_DISABLED;
- notifyStateMonitors();
- callback.onSuccess();
- }
-
- /**
- * Add a list of ForensicEvent.
- */
- public void addNewData(List<ForensicEvent> events) {
- mHandler.obtainMessage(MSG_TRANSPORT, events).sendToTarget();
- }
-
- private void transport(List<ForensicEvent> events) {
- mForensicEventTransportConnection.addData(events);
- }
-
- @Override
- public void onStart() {
- try {
- publishBinderService(Context.FORENSIC_SERVICE, mBinderService);
- } catch (Throwable t) {
- Slog.e(TAG, "Could not start the ForensicService.", t);
- }
- }
-
- @VisibleForTesting
- IForensicService getBinderService() {
- return mBinderService;
- }
-
- interface Injector {
- Context getContext();
-
- PermissionEnforcer getPermissionEnforcer();
-
- Looper getLooper();
-
- ForensicEventTransportConnection getForensicEventransportConnection();
-
- DataAggregator getDataAggregator(ForensicService forensicService);
- }
-
- private static final class InjectorImpl implements Injector {
- private final Context mContext;
-
- InjectorImpl(Context context) {
- mContext = context;
- }
-
- @Override
- public Context getContext() {
- return mContext;
- }
-
- @Override
- public PermissionEnforcer getPermissionEnforcer() {
- return PermissionEnforcer.fromContext(mContext);
- }
-
- @Override
- public Looper getLooper() {
- ServiceThread serviceThread =
- new ServiceThread(
- TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
- serviceThread.start();
- return serviceThread.getLooper();
- }
-
- @Override
- public ForensicEventTransportConnection getForensicEventransportConnection() {
- return new ForensicEventTransportConnection(mContext);
- }
-
- @Override
- public DataAggregator getDataAggregator(ForensicService forensicService) {
- return new DataAggregator(mContext, forensicService);
- }
- }
-}
-
diff --git a/services/core/java/com/android/server/security/forensic/OWNERS b/services/core/java/com/android/server/security/forensic/OWNERS
deleted file mode 100644
index 3bc3eb5..0000000
--- a/services/core/java/com/android/server/security/forensic/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file:platform/frameworks/base:main:/core/java/android/security/forensic/OWNERS
diff --git a/services/core/java/com/android/server/security/forensic/DataAggregator.java b/services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java
similarity index 78%
rename from services/core/java/com/android/server/security/forensic/DataAggregator.java
rename to services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java
index cc473ca..06e9dcd 100644
--- a/services/core/java/com/android/server/security/forensic/DataAggregator.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.security.forensic.ForensicEvent;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -30,22 +30,22 @@
import java.util.List;
public class DataAggregator {
- private static final String TAG = "Forensic DataAggregator";
+ private static final String TAG = "IntrusionDetection DataAggregator";
private static final int MSG_SINGLE_DATA = 0;
private static final int MSG_BATCH_DATA = 1;
private static final int MSG_DISABLE = 2;
private static final int STORED_EVENTS_SIZE_LIMIT = 1024;
- private final ForensicService mForensicService;
+ private final IntrusionDetectionService mIntrusionDetectionService;
private final ArrayList<DataSource> mDataSources;
private Context mContext;
- private List<ForensicEvent> mStoredEvents = new ArrayList<>();
+ private List<IntrusionDetectionEvent> mStoredEvents = new ArrayList<>();
private ServiceThread mHandlerThread;
private Handler mHandler;
- public DataAggregator(Context context, ForensicService forensicService) {
- mForensicService = forensicService;
+ public DataAggregator(Context context, IntrusionDetectionService intrusionDetectionService) {
+ mIntrusionDetectionService = intrusionDetectionService;
mContext = context;
mDataSources = new ArrayList<DataSource>();
}
@@ -83,14 +83,14 @@
/**
* DataSource calls it to transmit a single event.
*/
- public void addSingleData(ForensicEvent event) {
+ public void addSingleData(IntrusionDetectionEvent event) {
mHandler.obtainMessage(MSG_SINGLE_DATA, event).sendToTarget();
}
/**
* DataSource calls it to transmit list of events.
*/
- public void addBatchData(List<ForensicEvent> events) {
+ public void addBatchData(List<IntrusionDetectionEvent> events) {
mHandler.obtainMessage(MSG_BATCH_DATA, events).sendToTarget();
}
@@ -104,17 +104,17 @@
}
}
- private void onNewSingleData(ForensicEvent event) {
+ private void onNewSingleData(IntrusionDetectionEvent event) {
if (mStoredEvents.size() < STORED_EVENTS_SIZE_LIMIT) {
mStoredEvents.add(event);
} else {
- mForensicService.addNewData(mStoredEvents);
+ mIntrusionDetectionService.addNewData(mStoredEvents);
mStoredEvents = new ArrayList<>();
}
}
- private void onNewBatchData(List<ForensicEvent> events) {
- mForensicService.addNewData(events);
+ private void onNewBatchData(List<IntrusionDetectionEvent> events) {
+ mIntrusionDetectionService.addNewData(events);
}
private void onDisable() {
@@ -135,10 +135,10 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SINGLE_DATA:
- mDataAggregator.onNewSingleData((ForensicEvent) msg.obj);
+ mDataAggregator.onNewSingleData((IntrusionDetectionEvent) msg.obj);
break;
case MSG_BATCH_DATA:
- mDataAggregator.onNewBatchData((List<ForensicEvent>) msg.obj);
+ mDataAggregator.onNewBatchData((List<IntrusionDetectionEvent>) msg.obj);
break;
case MSG_DISABLE:
mDataAggregator.onDisable();
diff --git a/services/core/java/com/android/server/security/forensic/DataSource.java b/services/core/java/com/android/server/security/intrusiondetection/DataSource.java
similarity index 93%
rename from services/core/java/com/android/server/security/forensic/DataSource.java
rename to services/core/java/com/android/server/security/intrusiondetection/DataSource.java
index da7ee21..0bc4482 100644
--- a/services/core/java/com/android/server/security/forensic/DataSource.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/DataSource.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
public interface DataSource {
/**
diff --git a/services/core/java/com/android/server/security/forensic/ForensicEventTransportConnection.java b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
similarity index 74%
rename from services/core/java/com/android/server/security/forensic/ForensicEventTransportConnection.java
rename to services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
index b85199e..82f39b3 100644
--- a/services/core/java/com/android/server/security/forensic/ForensicEventTransportConnection.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
-import static android.Manifest.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE;
+import static android.Manifest.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE;
import android.content.ComponentName;
import android.content.Context;
@@ -27,8 +27,8 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.security.forensic.ForensicEvent;
-import android.security.forensic.IForensicEventTransport;
+import android.security.intrusiondetection.IIntrusionDetectionEventTransport;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import android.text.TextUtils;
import android.util.Slog;
@@ -40,20 +40,20 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-public class ForensicEventTransportConnection implements ServiceConnection {
- private static final String TAG = "ForensicEventTransportConnection";
+public class IntrusionDetectionEventTransportConnection implements ServiceConnection {
+ private static final String TAG = "IntrusionDetectionEventTransportConnection";
private static final long FUTURE_TIMEOUT_MILLIS = 60 * 1000; // 1 mins
private final Context mContext;
- private String mForensicEventTransportConfig;
- volatile IForensicEventTransport mService;
+ private String mIntrusionDetectionEventTransportConfig;
+ volatile IIntrusionDetectionEventTransport mService;
- public ForensicEventTransportConnection(Context context) {
+ public IntrusionDetectionEventTransportConnection(Context context) {
mContext = context;
mService = null;
}
/**
- * Initialize the ForensicEventTransport binder service.
+ * Initialize the IntrusionDetectionEventTransport binder service.
* @return Whether the initialization succeed.
*/
public boolean initialize() {
@@ -78,11 +78,11 @@
}
/**
- * Add data to the ForensicEventTransport binder service.
- * @param data List of ForensicEvent.
+ * Add data to the IntrusionDetectionEventTransport binder service.
+ * @param data List of IntrusionDetectionEvent.
* @return Whether the data is added to the binder service.
*/
- public boolean addData(List<ForensicEvent> data) {
+ public boolean addData(List<IntrusionDetectionEvent> data) {
AndroidFuture<Integer> resultFuture = new AndroidFuture<>();
try {
mService.addData(data, resultFuture);
@@ -119,15 +119,15 @@
}
private boolean bindService() {
- mForensicEventTransportConfig = mContext.getString(
- com.android.internal.R.string.config_forensicEventTransport);
- if (TextUtils.isEmpty(mForensicEventTransportConfig)) {
- Slog.e(TAG, "config_forensicEventTransport is empty");
+ mIntrusionDetectionEventTransportConfig = mContext.getString(
+ com.android.internal.R.string.config_intrusionDetectionEventTransport);
+ if (TextUtils.isEmpty(mIntrusionDetectionEventTransportConfig)) {
+ Slog.e(TAG, "config_intrusionDetectionEventTransport is empty");
return false;
}
ComponentName serviceComponent =
- ComponentName.unflattenFromString(mForensicEventTransportConfig);
+ ComponentName.unflattenFromString(mIntrusionDetectionEventTransportConfig);
if (serviceComponent == null) {
Slog.e(TAG, "Can't get serviceComponent name");
return false;
@@ -136,10 +136,10 @@
try {
ServiceInfo serviceInfo = mContext.getPackageManager().getServiceInfo(serviceComponent,
0 /* flags */);
- if (!BIND_FORENSIC_EVENT_TRANSPORT_SERVICE.equals(serviceInfo.permission)) {
+ if (!BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE.equals(serviceInfo.permission)) {
Slog.e(TAG, serviceComponent.flattenToShortString()
+ " is not declared with the permission "
- + "\"" + BIND_FORENSIC_EVENT_TRANSPORT_SERVICE + "\"");
+ + "\"" + BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE + "\"");
return false;
}
} catch (PackageManager.NameNotFoundException e) {
@@ -163,7 +163,7 @@
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- mService = IForensicEventTransport.Stub.asInterface(service);
+ mService = IIntrusionDetectionEventTransport.Stub.asInterface(service);
}
@Override
diff --git a/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionService.java b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionService.java
new file mode 100644
index 0000000..0287b41
--- /dev/null
+++ b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionService.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2024 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.server.security.intrusiondetection;
+
+import static android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE;
+import static android.Manifest.permission.READ_INTRUSION_DETECTION_STATE;
+
+import android.annotation.EnforcePermission;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PermissionEnforcer;
+import android.os.RemoteException;
+import android.security.intrusiondetection.IIntrusionDetectionService;
+import android.security.intrusiondetection.IIntrusionDetectionServiceCommandCallback;
+import android.security.intrusiondetection.IIntrusionDetectionServiceStateCallback;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.ServiceThread;
+import com.android.server.SystemService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @hide
+ */
+public class IntrusionDetectionService extends SystemService {
+ private static final String TAG = "IntrusionDetectionService";
+
+ private static final int MAX_STATE_CALLBACK_NUM = 16;
+ private static final int MSG_ADD_STATE_CALLBACK = 0;
+ private static final int MSG_REMOVE_STATE_CALLBACK = 1;
+ private static final int MSG_ENABLE = 2;
+ private static final int MSG_DISABLE = 3;
+ private static final int MSG_TRANSPORT = 4;
+
+ private static final int STATE_UNKNOWN =
+ IIntrusionDetectionServiceStateCallback.State.UNKNOWN;
+ private static final int STATE_DISABLED =
+ IIntrusionDetectionServiceStateCallback.State.DISABLED;
+ private static final int STATE_ENABLED =
+ IIntrusionDetectionServiceStateCallback.State.ENABLED;
+
+ private static final int ERROR_UNKNOWN =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.UNKNOWN;
+ private static final int ERROR_PERMISSION_DENIED =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
+ private static final int ERROR_INVALID_STATE_TRANSITION =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.INVALID_STATE_TRANSITION;
+ private static final int ERROR_TRANSPORT_UNAVAILABLE =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
+ private static final int ERROR_DATA_SOURCE_UNAVAILABLE =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final IntrusionDetectionEventTransportConnection
+ mIntrusionDetectionEventTransportConnection;
+ private final DataAggregator mDataAggregator;
+ private final BinderService mBinderService;
+
+ private final ArrayList<IIntrusionDetectionServiceStateCallback> mStateCallbacks =
+ new ArrayList<>();
+ private volatile int mState = STATE_DISABLED;
+
+ public IntrusionDetectionService(@NonNull Context context) {
+ this(new InjectorImpl(context));
+ }
+
+ @VisibleForTesting
+ IntrusionDetectionService(@NonNull Injector injector) {
+ super(injector.getContext());
+ mContext = injector.getContext();
+ mHandler = new EventHandler(injector.getLooper(), this);
+ mIntrusionDetectionEventTransportConnection =
+ injector.getIntrusionDetectionEventransportConnection();
+ mDataAggregator = injector.getDataAggregator(this);
+ mBinderService = new BinderService(this, injector.getPermissionEnforcer());
+ }
+
+ @VisibleForTesting
+ protected void setState(int state) {
+ mState = state;
+ }
+
+ private static final class BinderService extends IIntrusionDetectionService.Stub {
+ final IntrusionDetectionService mService;
+
+ BinderService(IntrusionDetectionService service,
+ @NonNull PermissionEnforcer permissionEnforcer) {
+ super(permissionEnforcer);
+ mService = service;
+ }
+
+ @Override
+ @EnforcePermission(READ_INTRUSION_DETECTION_STATE)
+ public void addStateCallback(IIntrusionDetectionServiceStateCallback callback) {
+ addStateCallback_enforcePermission();
+ mService.mHandler.obtainMessage(MSG_ADD_STATE_CALLBACK, callback).sendToTarget();
+ }
+
+ @Override
+ @EnforcePermission(READ_INTRUSION_DETECTION_STATE)
+ public void removeStateCallback(IIntrusionDetectionServiceStateCallback callback) {
+ removeStateCallback_enforcePermission();
+ mService.mHandler.obtainMessage(MSG_REMOVE_STATE_CALLBACK, callback).sendToTarget();
+ }
+
+ @Override
+ @EnforcePermission(MANAGE_INTRUSION_DETECTION_STATE)
+ public void enable(IIntrusionDetectionServiceCommandCallback callback) {
+ enable_enforcePermission();
+ mService.mHandler.obtainMessage(MSG_ENABLE, callback).sendToTarget();
+ }
+
+ @Override
+ @EnforcePermission(MANAGE_INTRUSION_DETECTION_STATE)
+ public void disable(IIntrusionDetectionServiceCommandCallback callback) {
+ disable_enforcePermission();
+ mService.mHandler.obtainMessage(MSG_DISABLE, callback).sendToTarget();
+ }
+ }
+
+ private static class EventHandler extends Handler {
+ private final IntrusionDetectionService mService;
+
+ EventHandler(Looper looper, IntrusionDetectionService service) {
+ super(looper);
+ mService = service;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ADD_STATE_CALLBACK:
+ try {
+ mService.addStateCallback(
+ (IIntrusionDetectionServiceStateCallback) msg.obj);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException", e);
+ }
+ break;
+ case MSG_REMOVE_STATE_CALLBACK:
+ try {
+ mService.removeStateCallback(
+ (IIntrusionDetectionServiceStateCallback) msg.obj);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException", e);
+ }
+ break;
+ case MSG_ENABLE:
+ try {
+ mService.enable((IIntrusionDetectionServiceCommandCallback) msg.obj);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException", e);
+ }
+ break;
+ case MSG_DISABLE:
+ try {
+ mService.disable((IIntrusionDetectionServiceCommandCallback) msg.obj);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException", e);
+ }
+ break;
+ case MSG_TRANSPORT:
+ mService.transport((List<IntrusionDetectionEvent>) msg.obj);
+ break;
+ default:
+ Slog.w(TAG, "Unknown message: " + msg.what);
+ }
+ }
+ }
+
+ private void addStateCallback(IIntrusionDetectionServiceStateCallback callback)
+ throws RemoteException {
+ for (int i = 0; i < mStateCallbacks.size(); i++) {
+ if (mStateCallbacks.get(i).asBinder() == callback.asBinder()) {
+ return;
+ }
+ }
+ mStateCallbacks.add(callback);
+ callback.onStateChange(mState);
+ }
+
+ private void removeStateCallback(IIntrusionDetectionServiceStateCallback callback)
+ throws RemoteException {
+ for (int i = 0; i < mStateCallbacks.size(); i++) {
+ if (mStateCallbacks.get(i).asBinder() == callback.asBinder()) {
+ mStateCallbacks.remove(i);
+ return;
+ }
+ }
+ }
+
+ private void notifyStateMonitors() {
+ if (mStateCallbacks.size() >= MAX_STATE_CALLBACK_NUM) {
+ mStateCallbacks.removeFirst();
+ }
+
+ for (int i = 0; i < mStateCallbacks.size(); i++) {
+ try {
+ mStateCallbacks.get(i).onStateChange(mState);
+ } catch (RemoteException e) {
+ mStateCallbacks.remove(i);
+ }
+ }
+ }
+
+ private void enable(IIntrusionDetectionServiceCommandCallback callback)
+ throws RemoteException {
+ if (mState == STATE_ENABLED) {
+ callback.onSuccess();
+ return;
+ }
+
+ // TODO: temporarily disable the following for the CTS IntrusionDetectionManagerTest.
+ // Enable it when the transport component is ready.
+ // if (!mIntrusionDetectionEventTransportConnection.initialize()) {
+ // callback.onFailure(ERROR_TRANSPORT_UNAVAILABLE);
+ // return;
+ // }
+
+ mDataAggregator.enable();
+ mState = STATE_ENABLED;
+ notifyStateMonitors();
+ callback.onSuccess();
+ }
+
+ private void disable(IIntrusionDetectionServiceCommandCallback callback)
+ throws RemoteException {
+ if (mState == STATE_DISABLED) {
+ callback.onSuccess();
+ return;
+ }
+
+ // TODO: temporarily disable the following for the CTS IntrusionDetectionManagerTest.
+ // Enable it when the transport component is ready.
+ // mIntrusionDetectionEventTransportConnection.release();
+ mDataAggregator.disable();
+ mState = STATE_DISABLED;
+ notifyStateMonitors();
+ callback.onSuccess();
+ }
+
+ /**
+ * Add a list of IntrusionDetectionEvent.
+ */
+ public void addNewData(List<IntrusionDetectionEvent> events) {
+ mHandler.obtainMessage(MSG_TRANSPORT, events).sendToTarget();
+ }
+
+ private void transport(List<IntrusionDetectionEvent> events) {
+ mIntrusionDetectionEventTransportConnection.addData(events);
+ }
+
+ @Override
+ public void onStart() {
+ try {
+ publishBinderService(Context.INTRUSION_DETECTION_SERVICE, mBinderService);
+ } catch (Throwable t) {
+ Slog.e(TAG, "Could not start the IntrusionDetectionService.", t);
+ }
+ }
+
+ @VisibleForTesting
+ IIntrusionDetectionService getBinderService() {
+ return mBinderService;
+ }
+
+ interface Injector {
+ Context getContext();
+
+ PermissionEnforcer getPermissionEnforcer();
+
+ Looper getLooper();
+
+ IntrusionDetectionEventTransportConnection getIntrusionDetectionEventransportConnection();
+
+ DataAggregator getDataAggregator(IntrusionDetectionService intrusionDetectionService);
+ }
+
+ private static final class InjectorImpl implements Injector {
+ private final Context mContext;
+
+ InjectorImpl(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public Context getContext() {
+ return mContext;
+ }
+
+ @Override
+ public PermissionEnforcer getPermissionEnforcer() {
+ return PermissionEnforcer.fromContext(mContext);
+ }
+
+ @Override
+ public Looper getLooper() {
+ ServiceThread serviceThread =
+ new ServiceThread(
+ TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
+ serviceThread.start();
+ return serviceThread.getLooper();
+ }
+
+ @Override
+ public IntrusionDetectionEventTransportConnection
+ getIntrusionDetectionEventransportConnection() {
+ return new IntrusionDetectionEventTransportConnection(mContext);
+ }
+
+ @Override
+ public DataAggregator getDataAggregator(
+ IntrusionDetectionService intrusionDetectionService) {
+ return new DataAggregator(mContext, intrusionDetectionService);
+ }
+ }
+}
+
diff --git a/services/core/java/com/android/server/security/intrusiondetection/OWNERS b/services/core/java/com/android/server/security/intrusiondetection/OWNERS
new file mode 100644
index 0000000..0508067
--- /dev/null
+++ b/services/core/java/com/android/server/security/intrusiondetection/OWNERS
@@ -0,0 +1 @@
+file:platform/frameworks/base:main:/core/java/android/security/intrusiondetection/OWNERS
diff --git a/services/core/java/com/android/server/security/forensic/SecurityLogSource.java b/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
similarity index 87%
rename from services/core/java/com/android/server/security/forensic/SecurityLogSource.java
rename to services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
index e1b49c4..226f9d8 100644
--- a/services/core/java/com/android/server/security/forensic/SecurityLogSource.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
import android.Manifest.permission;
import android.annotation.RequiresPermission;
import android.app.admin.DevicePolicyManager;
import android.app.admin.SecurityLog.SecurityEvent;
import android.content.Context;
-import android.security.forensic.ForensicEvent;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import java.util.List;
import java.util.concurrent.Executor;
@@ -31,7 +31,7 @@
public class SecurityLogSource implements DataSource {
- private static final String TAG = "Forensic SecurityLogSource";
+ private static final String TAG = "IntrusionDetection SecurityLogSource";
private SecurityEventCallback mEventCallback = new SecurityEventCallback();
private DevicePolicyManager mDpm;
@@ -85,12 +85,12 @@
@Override
public void accept(List<SecurityEvent> events) {
- List<ForensicEvent> forensicEvents =
+ List<IntrusionDetectionEvent> intrusionDetectionEvents =
events.stream()
.filter(event -> event != null)
- .map(event -> new ForensicEvent(event))
+ .map(event -> new IntrusionDetectionEvent(event))
.collect(Collectors.toList());
- mDataAggregator.addBatchData(forensicEvents);
+ mDataAggregator.addBatchData(intrusionDetectionEvents);
}
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index dc10dd9..980fcac 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -252,7 +252,7 @@
import com.android.server.security.advancedprotection.AdvancedProtectionService;
import com.android.server.security.authenticationpolicy.AuthenticationPolicyService;
import com.android.server.security.authenticationpolicy.SecureLockDeviceService;
-import com.android.server.security.forensic.ForensicService;
+import com.android.server.security.intrusiondetection.IntrusionDetectionService;
import com.android.server.security.rkp.RemoteProvisioningService;
import com.android.server.selinux.SelinuxAuditLogsService;
import com.android.server.sensorprivacy.SensorPrivacyService;
@@ -1764,8 +1764,8 @@
if (!isWatch && !isTv && !isAutomotive
&& android.security.Flags.aflApi()) {
- t.traceBegin("StartForensicService");
- mSystemServiceManager.startService(ForensicService.class);
+ t.traceBegin("StartIntrusionDetectionService");
+ mSystemServiceManager.startService(IntrusionDetectionService.class);
t.traceEnd();
}
diff --git a/services/tests/security/forensic/OWNERS b/services/tests/security/forensic/OWNERS
deleted file mode 100644
index 80c9afb9..0000000
--- a/services/tests/security/forensic/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 36824
-
-file:platform/frameworks/base:main:/core/java/android/security/forensic/OWNERS
diff --git a/services/tests/security/forensic/TEST_MAPPING b/services/tests/security/forensic/TEST_MAPPING
deleted file mode 100644
index bd8b2ab..0000000
--- a/services/tests/security/forensic/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "postsubmit": [
- {
- "name": "ForensicServiceTests"
- }
- ]
-}
diff --git a/services/tests/security/forensic/src/com/android/server/security/forensic/ForensicServiceTest.java b/services/tests/security/forensic/src/com/android/server/security/forensic/ForensicServiceTest.java
deleted file mode 100644
index 03c449c..0000000
--- a/services/tests/security/forensic/src/com/android/server/security/forensic/ForensicServiceTest.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2024 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.server.security.forensic;
-
-import static android.Manifest.permission.MANAGE_FORENSIC_STATE;
-import static android.Manifest.permission.READ_FORENSIC_STATE;
-
-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.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.annotation.SuppressLint;
-import android.app.admin.ConnectEvent;
-import android.app.admin.DnsEvent;
-import android.app.admin.SecurityLog.SecurityEvent;
-import android.content.Context;
-import android.os.Looper;
-import android.os.PermissionEnforcer;
-import android.os.RemoteException;
-import android.os.test.FakePermissionEnforcer;
-import android.os.test.TestLooper;
-import android.security.forensic.ForensicEvent;
-import android.security.forensic.IForensicServiceCommandCallback;
-import android.security.forensic.IForensicServiceStateCallback;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.ServiceThread;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ForensicServiceTest {
- private static final int STATE_UNKNOWN = IForensicServiceStateCallback.State.UNKNOWN;
- private static final int STATE_DISABLED = IForensicServiceStateCallback.State.DISABLED;
- private static final int STATE_ENABLED = IForensicServiceStateCallback.State.ENABLED;
-
- private static final int ERROR_UNKNOWN = IForensicServiceCommandCallback.ErrorCode.UNKNOWN;
- private static final int ERROR_PERMISSION_DENIED =
- IForensicServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
- private static final int ERROR_TRANSPORT_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
- private static final int ERROR_DATA_SOURCE_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
-
- private Context mContext;
- private ForensicEventTransportConnection mForensicEventTransportConnection;
- private DataAggregator mDataAggregator;
- private ForensicService mForensicService;
- private TestLooper mTestLooper;
- private Looper mLooper;
- private TestLooper mTestLooperOfDataAggregator;
- private Looper mLooperOfDataAggregator;
- private FakePermissionEnforcer mPermissionEnforcer;
-
- @SuppressLint("VisibleForTests")
- @Before
- public void setUp() {
- mContext = spy(ApplicationProvider.getApplicationContext());
-
- mPermissionEnforcer = new FakePermissionEnforcer();
- mPermissionEnforcer.grant(READ_FORENSIC_STATE);
- mPermissionEnforcer.grant(MANAGE_FORENSIC_STATE);
-
- mTestLooper = new TestLooper();
- mLooper = mTestLooper.getLooper();
- mTestLooperOfDataAggregator = new TestLooper();
- mLooperOfDataAggregator = mTestLooperOfDataAggregator.getLooper();
- mForensicService = new ForensicService(new MockInjector(mContext));
- mForensicService.onStart();
- }
-
- @Test
- public void testAddStateCallback_NoPermission() {
- mPermissionEnforcer.revoke(READ_FORENSIC_STATE);
- StateCallback scb = new StateCallback();
- assertEquals(STATE_UNKNOWN, scb.mState);
- assertThrows(SecurityException.class,
- () -> mForensicService.getBinderService().addStateCallback(scb));
- }
-
- @Test
- public void testRemoveStateCallback_NoPermission() {
- mPermissionEnforcer.revoke(READ_FORENSIC_STATE);
- StateCallback scb = new StateCallback();
- assertEquals(STATE_UNKNOWN, scb.mState);
- assertThrows(SecurityException.class,
- () -> mForensicService.getBinderService().removeStateCallback(scb));
- }
-
- @Test
- public void testEnable_NoPermission() {
- mPermissionEnforcer.revoke(MANAGE_FORENSIC_STATE);
-
- CommandCallback ccb = new CommandCallback();
- assertThrows(SecurityException.class,
- () -> mForensicService.getBinderService().enable(ccb));
- }
-
- @Test
- public void testDisable_NoPermission() {
- mPermissionEnforcer.revoke(MANAGE_FORENSIC_STATE);
-
- CommandCallback ccb = new CommandCallback();
- assertThrows(SecurityException.class,
- () -> mForensicService.getBinderService().disable(ccb));
- }
-
- @Test
- public void testAddStateCallback_Disabled() throws RemoteException {
- StateCallback scb = new StateCallback();
- assertEquals(STATE_UNKNOWN, scb.mState);
- mForensicService.getBinderService().addStateCallback(scb);
- mTestLooper.dispatchAll();
- assertEquals(STATE_DISABLED, scb.mState);
- }
-
- @Test
- public void testAddStateCallback_Disabled_TwoStateCallbacks() throws RemoteException {
- StateCallback scb1 = new StateCallback();
- assertEquals(STATE_UNKNOWN, scb1.mState);
- mForensicService.getBinderService().addStateCallback(scb1);
- mTestLooper.dispatchAll();
- assertEquals(STATE_DISABLED, scb1.mState);
-
- StateCallback scb2 = new StateCallback();
- assertEquals(STATE_UNKNOWN, scb2.mState);
- mForensicService.getBinderService().addStateCallback(scb2);
- mTestLooper.dispatchAll();
- assertEquals(STATE_DISABLED, scb2.mState);
- }
-
- @Test
- public void testRemoveStateCallback() throws RemoteException {
- mForensicService.setState(STATE_DISABLED);
- StateCallback scb1 = new StateCallback();
- StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
- mTestLooper.dispatchAll();
- assertEquals(STATE_DISABLED, scb1.mState);
- assertEquals(STATE_DISABLED, scb2.mState);
-
- doReturn(true).when(mDataAggregator).initialize();
- doReturn(true).when(mForensicEventTransportConnection).initialize();
-
- mForensicService.getBinderService().removeStateCallback(scb2);
-
- CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().enable(ccb);
- mTestLooper.dispatchAll();
- assertEquals(STATE_ENABLED, scb1.mState);
- assertEquals(STATE_DISABLED, scb2.mState);
- assertNull(ccb.mErrorCode);
- }
-
- @Test
- public void testEnable_FromDisabled_TwoStateCallbacks() throws RemoteException {
- mForensicService.setState(STATE_DISABLED);
- StateCallback scb1 = new StateCallback();
- StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
- mTestLooper.dispatchAll();
- assertEquals(STATE_DISABLED, scb1.mState);
- assertEquals(STATE_DISABLED, scb2.mState);
-
- doReturn(true).when(mForensicEventTransportConnection).initialize();
-
- CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().enable(ccb);
- mTestLooper.dispatchAll();
-
- verify(mDataAggregator, times(1)).enable();
- assertEquals(STATE_ENABLED, scb1.mState);
- assertEquals(STATE_ENABLED, scb2.mState);
- assertNull(ccb.mErrorCode);
- }
-
- @Test
- public void testEnable_FromEnabled_TwoStateCallbacks()
- throws RemoteException {
- mForensicService.setState(STATE_ENABLED);
- StateCallback scb1 = new StateCallback();
- StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
- mTestLooper.dispatchAll();
- assertEquals(STATE_ENABLED, scb1.mState);
- assertEquals(STATE_ENABLED, scb2.mState);
-
- CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().enable(ccb);
- mTestLooper.dispatchAll();
-
- assertEquals(STATE_ENABLED, scb1.mState);
- assertEquals(STATE_ENABLED, scb2.mState);
- assertNull(ccb.mErrorCode);
- }
-
- @Test
- public void testDisable_FromDisabled_TwoStateCallbacks() throws RemoteException {
- mForensicService.setState(STATE_DISABLED);
- StateCallback scb1 = new StateCallback();
- StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
- mTestLooper.dispatchAll();
- assertEquals(STATE_DISABLED, scb1.mState);
- assertEquals(STATE_DISABLED, scb2.mState);
-
- CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().disable(ccb);
- mTestLooper.dispatchAll();
-
- assertEquals(STATE_DISABLED, scb1.mState);
- assertEquals(STATE_DISABLED, scb2.mState);
- assertNull(ccb.mErrorCode);
- }
-
- @Test
- public void testDisable_FromEnabled_TwoStateCallbacks() throws RemoteException {
- mForensicService.setState(STATE_ENABLED);
- StateCallback scb1 = new StateCallback();
- StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
- mTestLooper.dispatchAll();
- assertEquals(STATE_ENABLED, scb1.mState);
- assertEquals(STATE_ENABLED, scb2.mState);
-
- doNothing().when(mForensicEventTransportConnection).release();
-
- ServiceThread mockThread = spy(ServiceThread.class);
- mDataAggregator.setHandler(mLooperOfDataAggregator, mockThread);
-
- CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().disable(ccb);
- mTestLooper.dispatchAll();
- mTestLooperOfDataAggregator.dispatchAll();
- // TODO: We can verify the data sources once we implement them.
- verify(mockThread, times(1)).quitSafely();
- assertEquals(STATE_DISABLED, scb1.mState);
- assertEquals(STATE_DISABLED, scb2.mState);
- assertNull(ccb.mErrorCode);
- }
-
- @Ignore("Enable once the ForensicEventTransportConnection is ready")
- @Test
- public void testEnable_FromDisable_TwoStateCallbacks_TransportUnavailable()
- throws RemoteException {
- mForensicService.setState(STATE_DISABLED);
- StateCallback scb1 = new StateCallback();
- StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
- mTestLooper.dispatchAll();
- assertEquals(STATE_DISABLED, scb1.mState);
- assertEquals(STATE_DISABLED, scb2.mState);
-
- doReturn(false).when(mForensicEventTransportConnection).initialize();
-
- CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().enable(ccb);
- mTestLooper.dispatchAll();
- assertEquals(STATE_DISABLED, scb1.mState);
- assertEquals(STATE_DISABLED, scb2.mState);
- assertNotNull(ccb.mErrorCode);
- assertEquals(ERROR_TRANSPORT_UNAVAILABLE, ccb.mErrorCode.intValue());
- }
-
- @Test
- public void testDataAggregator_AddBatchData() {
- mForensicService.setState(STATE_ENABLED);
- ServiceThread mockThread = spy(ServiceThread.class);
- mDataAggregator.setHandler(mLooperOfDataAggregator, mockThread);
-
- SecurityEvent securityEvent = new SecurityEvent(0, new byte[0]);
- ForensicEvent eventOne = new ForensicEvent(securityEvent);
-
- ConnectEvent connectEvent = new ConnectEvent("127.0.0.1", 80, null, 0);
- ForensicEvent eventTwo = new ForensicEvent(connectEvent);
-
- DnsEvent dnsEvent = new DnsEvent(null, new String[] {"127.0.0.1"}, 1, null, 0);
- ForensicEvent eventThree = new ForensicEvent(dnsEvent);
-
- List<ForensicEvent> events = new ArrayList<>();
- events.add(eventOne);
- events.add(eventTwo);
- events.add(eventThree);
-
- doReturn(true).when(mForensicEventTransportConnection).addData(any());
-
- mDataAggregator.addBatchData(events);
- mTestLooperOfDataAggregator.dispatchAll();
- mTestLooper.dispatchAll();
-
- ArgumentCaptor<List<ForensicEvent>> captor = ArgumentCaptor.forClass(List.class);
- verify(mForensicEventTransportConnection).addData(captor.capture());
- List<ForensicEvent> receivedEvents = captor.getValue();
- assertEquals(receivedEvents.size(), 3);
-
- assertEquals(receivedEvents.get(0).getType(), ForensicEvent.SECURITY_EVENT);
- assertNotNull(receivedEvents.get(0).getSecurityEvent());
-
- assertEquals(receivedEvents.get(1).getType(), ForensicEvent.NETWORK_EVENT_CONNECT);
- assertNotNull(receivedEvents.get(1).getConnectEvent());
-
- assertEquals(receivedEvents.get(2).getType(), ForensicEvent.NETWORK_EVENT_DNS);
- assertNotNull(receivedEvents.get(2).getDnsEvent());
- }
-
- private class MockInjector implements ForensicService.Injector {
- private final Context mContext;
-
- MockInjector(Context context) {
- mContext = context;
- }
-
- @Override
- public Context getContext() {
- return mContext;
- }
-
- @Override
- public PermissionEnforcer getPermissionEnforcer() {
- return mPermissionEnforcer;
- }
-
- @Override
- public Looper getLooper() {
- return mLooper;
- }
-
- @Override
- public ForensicEventTransportConnection getForensicEventransportConnection() {
- mForensicEventTransportConnection = spy(new ForensicEventTransportConnection(mContext));
- return mForensicEventTransportConnection;
- }
-
- @Override
- public DataAggregator getDataAggregator(ForensicService forensicService) {
- mDataAggregator = spy(new DataAggregator(mContext, forensicService));
- return mDataAggregator;
- }
- }
-
- private static class StateCallback extends IForensicServiceStateCallback.Stub {
- int mState = STATE_UNKNOWN;
-
- @Override
- public void onStateChange(int state) throws RemoteException {
- mState = state;
- }
- }
-
- private static class CommandCallback extends IForensicServiceCommandCallback.Stub {
- Integer mErrorCode = null;
-
- public void reset() {
- mErrorCode = null;
- }
-
- @Override
- public void onSuccess() throws RemoteException {
-
- }
-
- @Override
- public void onFailure(int errorCode) throws RemoteException {
- mErrorCode = errorCode;
- }
- }
-}
diff --git a/services/tests/security/forensic/Android.bp b/services/tests/security/intrusiondetection/Android.bp
similarity index 95%
rename from services/tests/security/forensic/Android.bp
rename to services/tests/security/intrusiondetection/Android.bp
index 77a87af..00ac908 100644
--- a/services/tests/security/forensic/Android.bp
+++ b/services/tests/security/intrusiondetection/Android.bp
@@ -9,7 +9,7 @@
}
android_test {
- name: "ForensicServiceTests",
+ name: "IntrusionDetectionServiceTests",
srcs: [
"src/**/*.java",
],
diff --git a/services/tests/security/forensic/AndroidManifest.xml b/services/tests/security/intrusiondetection/AndroidManifest.xml
similarity index 83%
rename from services/tests/security/forensic/AndroidManifest.xml
rename to services/tests/security/intrusiondetection/AndroidManifest.xml
index c5b3d40..f388e7e 100644
--- a/services/tests/security/forensic/AndroidManifest.xml
+++ b/services/tests/security/intrusiondetection/AndroidManifest.xml
@@ -15,7 +15,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.security.forensic.tests">
+ package="com.android.server.security.intrusiondetection.tests">
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
@@ -25,6 +25,6 @@
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.server.security.forensic.tests"
- android:label="Frameworks Forensic Services Tests"/>
+ android:targetPackage="com.android.server.security.intrusiondetection.tests"
+ android:label="Frameworks IntrusionDetection Services Tests"/>
</manifest>
diff --git a/services/tests/security/forensic/AndroidTest.xml b/services/tests/security/intrusiondetection/AndroidTest.xml
similarity index 82%
rename from services/tests/security/forensic/AndroidTest.xml
rename to services/tests/security/intrusiondetection/AndroidTest.xml
index bbe2e9c..42cb9e3 100644
--- a/services/tests/security/forensic/AndroidTest.xml
+++ b/services/tests/security/intrusiondetection/AndroidTest.xml
@@ -13,19 +13,19 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Runs Frameworks Forensic Service tests.">
+<configuration description="Runs Frameworks IntrusionDetection Service tests.">
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-instrumentation" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true"/>
- <option name="test-file-name" value="ForensicServiceTests.apk"/>
+ <option name="test-file-name" value="IntrusionDetectionServiceTests.apk"/>
<option name="install-arg" value="-t" />
</target_preparer>
- <option name="test-tag" value="ForensicServiceTests" />
+ <option name="test-tag" value="IntrusionDetectionServiceTests" />
<test class="com.android.tradefed.testtype.InstrumentationTest" >
- <option name="package" value="com.android.server.security.forensic.tests" />
+ <option name="package" value="com.android.server.security.intrusiondetection.tests" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
diff --git a/services/tests/security/intrusiondetection/OWNERS b/services/tests/security/intrusiondetection/OWNERS
new file mode 100644
index 0000000..2157972
--- /dev/null
+++ b/services/tests/security/intrusiondetection/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 36824
+
+file:platform/frameworks/base:main:/core/java/android/security/intrusiondetection/OWNERS
diff --git a/services/tests/security/intrusiondetection/TEST_MAPPING b/services/tests/security/intrusiondetection/TEST_MAPPING
new file mode 100644
index 0000000..24d63e3
--- /dev/null
+++ b/services/tests/security/intrusiondetection/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "postsubmit": [
+ {
+ "name": "IntrusionDetectionServiceTests"
+ }
+ ]
+}
diff --git a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
new file mode 100644
index 0000000..bc854cf
--- /dev/null
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2024 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.server.security.intrusiondetection;
+
+import static android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE;
+import static android.Manifest.permission.READ_INTRUSION_DETECTION_STATE;
+
+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.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.annotation.SuppressLint;
+import android.app.admin.ConnectEvent;
+import android.app.admin.DnsEvent;
+import android.app.admin.SecurityLog.SecurityEvent;
+import android.content.Context;
+import android.os.Looper;
+import android.os.PermissionEnforcer;
+import android.os.RemoteException;
+import android.os.test.FakePermissionEnforcer;
+import android.os.test.TestLooper;
+import android.security.intrusiondetection.IIntrusionDetectionServiceCommandCallback;
+import android.security.intrusiondetection.IIntrusionDetectionServiceStateCallback;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.server.ServiceThread;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class IntrusionDetectionServiceTest {
+ private static final int STATE_UNKNOWN =
+ IIntrusionDetectionServiceStateCallback.State.UNKNOWN;
+ private static final int STATE_DISABLED =
+ IIntrusionDetectionServiceStateCallback.State.DISABLED;
+ private static final int STATE_ENABLED =
+ IIntrusionDetectionServiceStateCallback.State.ENABLED;
+
+ private static final int ERROR_UNKNOWN =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.UNKNOWN;
+ private static final int ERROR_PERMISSION_DENIED =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
+ private static final int ERROR_TRANSPORT_UNAVAILABLE =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
+ private static final int ERROR_DATA_SOURCE_UNAVAILABLE =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
+
+ private Context mContext;
+ private IntrusionDetectionEventTransportConnection mIntrusionDetectionEventTransportConnection;
+ private DataAggregator mDataAggregator;
+ private IntrusionDetectionService mIntrusionDetectionService;
+ private TestLooper mTestLooper;
+ private Looper mLooper;
+ private TestLooper mTestLooperOfDataAggregator;
+ private Looper mLooperOfDataAggregator;
+ private FakePermissionEnforcer mPermissionEnforcer;
+
+ @SuppressLint("VisibleForTests")
+ @Before
+ public void setUp() {
+ mContext = spy(ApplicationProvider.getApplicationContext());
+
+ mPermissionEnforcer = new FakePermissionEnforcer();
+ mPermissionEnforcer.grant(READ_INTRUSION_DETECTION_STATE);
+ mPermissionEnforcer.grant(MANAGE_INTRUSION_DETECTION_STATE);
+
+ mTestLooper = new TestLooper();
+ mLooper = mTestLooper.getLooper();
+ mTestLooperOfDataAggregator = new TestLooper();
+ mLooperOfDataAggregator = mTestLooperOfDataAggregator.getLooper();
+ mIntrusionDetectionService = new IntrusionDetectionService(new MockInjector(mContext));
+ mIntrusionDetectionService.onStart();
+ }
+
+ @Test
+ public void testAddStateCallback_NoPermission() {
+ mPermissionEnforcer.revoke(READ_INTRUSION_DETECTION_STATE);
+ StateCallback scb = new StateCallback();
+ assertEquals(STATE_UNKNOWN, scb.mState);
+ assertThrows(SecurityException.class,
+ () -> mIntrusionDetectionService.getBinderService().addStateCallback(scb));
+ }
+
+ @Test
+ public void testRemoveStateCallback_NoPermission() {
+ mPermissionEnforcer.revoke(READ_INTRUSION_DETECTION_STATE);
+ StateCallback scb = new StateCallback();
+ assertEquals(STATE_UNKNOWN, scb.mState);
+ assertThrows(SecurityException.class,
+ () -> mIntrusionDetectionService.getBinderService().removeStateCallback(scb));
+ }
+
+ @Test
+ public void testEnable_NoPermission() {
+ mPermissionEnforcer.revoke(MANAGE_INTRUSION_DETECTION_STATE);
+
+ CommandCallback ccb = new CommandCallback();
+ assertThrows(SecurityException.class,
+ () -> mIntrusionDetectionService.getBinderService().enable(ccb));
+ }
+
+ @Test
+ public void testDisable_NoPermission() {
+ mPermissionEnforcer.revoke(MANAGE_INTRUSION_DETECTION_STATE);
+
+ CommandCallback ccb = new CommandCallback();
+ assertThrows(SecurityException.class,
+ () -> mIntrusionDetectionService.getBinderService().disable(ccb));
+ }
+
+ @Test
+ public void testAddStateCallback_Disabled() throws RemoteException {
+ StateCallback scb = new StateCallback();
+ assertEquals(STATE_UNKNOWN, scb.mState);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_DISABLED, scb.mState);
+ }
+
+ @Test
+ public void testAddStateCallback_Disabled_TwoStateCallbacks() throws RemoteException {
+ StateCallback scb1 = new StateCallback();
+ assertEquals(STATE_UNKNOWN, scb1.mState);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_DISABLED, scb1.mState);
+
+ StateCallback scb2 = new StateCallback();
+ assertEquals(STATE_UNKNOWN, scb2.mState);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_DISABLED, scb2.mState);
+ }
+
+ @Test
+ public void testRemoveStateCallback() throws RemoteException {
+ mIntrusionDetectionService.setState(STATE_DISABLED);
+ StateCallback scb1 = new StateCallback();
+ StateCallback scb2 = new StateCallback();
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_DISABLED, scb1.mState);
+ assertEquals(STATE_DISABLED, scb2.mState);
+
+ doReturn(true).when(mDataAggregator).initialize();
+ doReturn(true).when(mIntrusionDetectionEventTransportConnection).initialize();
+
+ mIntrusionDetectionService.getBinderService().removeStateCallback(scb2);
+
+ CommandCallback ccb = new CommandCallback();
+ mIntrusionDetectionService.getBinderService().enable(ccb);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_ENABLED, scb1.mState);
+ assertEquals(STATE_DISABLED, scb2.mState);
+ assertNull(ccb.mErrorCode);
+ }
+
+ @Test
+ public void testEnable_FromDisabled_TwoStateCallbacks() throws RemoteException {
+ mIntrusionDetectionService.setState(STATE_DISABLED);
+ StateCallback scb1 = new StateCallback();
+ StateCallback scb2 = new StateCallback();
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_DISABLED, scb1.mState);
+ assertEquals(STATE_DISABLED, scb2.mState);
+
+ doReturn(true).when(mIntrusionDetectionEventTransportConnection).initialize();
+
+ CommandCallback ccb = new CommandCallback();
+ mIntrusionDetectionService.getBinderService().enable(ccb);
+ mTestLooper.dispatchAll();
+
+ verify(mDataAggregator, times(1)).enable();
+ assertEquals(STATE_ENABLED, scb1.mState);
+ assertEquals(STATE_ENABLED, scb2.mState);
+ assertNull(ccb.mErrorCode);
+ }
+
+ @Test
+ public void testEnable_FromEnabled_TwoStateCallbacks()
+ throws RemoteException {
+ mIntrusionDetectionService.setState(STATE_ENABLED);
+ StateCallback scb1 = new StateCallback();
+ StateCallback scb2 = new StateCallback();
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_ENABLED, scb1.mState);
+ assertEquals(STATE_ENABLED, scb2.mState);
+
+ CommandCallback ccb = new CommandCallback();
+ mIntrusionDetectionService.getBinderService().enable(ccb);
+ mTestLooper.dispatchAll();
+
+ assertEquals(STATE_ENABLED, scb1.mState);
+ assertEquals(STATE_ENABLED, scb2.mState);
+ assertNull(ccb.mErrorCode);
+ }
+
+ @Test
+ public void testDisable_FromDisabled_TwoStateCallbacks() throws RemoteException {
+ mIntrusionDetectionService.setState(STATE_DISABLED);
+ StateCallback scb1 = new StateCallback();
+ StateCallback scb2 = new StateCallback();
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_DISABLED, scb1.mState);
+ assertEquals(STATE_DISABLED, scb2.mState);
+
+ CommandCallback ccb = new CommandCallback();
+ mIntrusionDetectionService.getBinderService().disable(ccb);
+ mTestLooper.dispatchAll();
+
+ assertEquals(STATE_DISABLED, scb1.mState);
+ assertEquals(STATE_DISABLED, scb2.mState);
+ assertNull(ccb.mErrorCode);
+ }
+
+ @Test
+ public void testDisable_FromEnabled_TwoStateCallbacks() throws RemoteException {
+ mIntrusionDetectionService.setState(STATE_ENABLED);
+ StateCallback scb1 = new StateCallback();
+ StateCallback scb2 = new StateCallback();
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_ENABLED, scb1.mState);
+ assertEquals(STATE_ENABLED, scb2.mState);
+
+ doNothing().when(mIntrusionDetectionEventTransportConnection).release();
+
+ ServiceThread mockThread = spy(ServiceThread.class);
+ mDataAggregator.setHandler(mLooperOfDataAggregator, mockThread);
+
+ CommandCallback ccb = new CommandCallback();
+ mIntrusionDetectionService.getBinderService().disable(ccb);
+ mTestLooper.dispatchAll();
+ mTestLooperOfDataAggregator.dispatchAll();
+ // TODO: We can verify the data sources once we implement them.
+ verify(mockThread, times(1)).quitSafely();
+ assertEquals(STATE_DISABLED, scb1.mState);
+ assertEquals(STATE_DISABLED, scb2.mState);
+ assertNull(ccb.mErrorCode);
+ }
+
+ @Ignore("Enable once the IntrusionDetectionEventTransportConnection is ready")
+ @Test
+ public void testEnable_FromDisable_TwoStateCallbacks_TransportUnavailable()
+ throws RemoteException {
+ mIntrusionDetectionService.setState(STATE_DISABLED);
+ StateCallback scb1 = new StateCallback();
+ StateCallback scb2 = new StateCallback();
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_DISABLED, scb1.mState);
+ assertEquals(STATE_DISABLED, scb2.mState);
+
+ doReturn(false).when(mIntrusionDetectionEventTransportConnection).initialize();
+
+ CommandCallback ccb = new CommandCallback();
+ mIntrusionDetectionService.getBinderService().enable(ccb);
+ mTestLooper.dispatchAll();
+ assertEquals(STATE_DISABLED, scb1.mState);
+ assertEquals(STATE_DISABLED, scb2.mState);
+ assertNotNull(ccb.mErrorCode);
+ assertEquals(ERROR_TRANSPORT_UNAVAILABLE, ccb.mErrorCode.intValue());
+ }
+
+ @Test
+ public void testDataAggregator_AddBatchData() {
+ mIntrusionDetectionService.setState(STATE_ENABLED);
+ ServiceThread mockThread = spy(ServiceThread.class);
+ mDataAggregator.setHandler(mLooperOfDataAggregator, mockThread);
+
+ SecurityEvent securityEvent = new SecurityEvent(0, new byte[0]);
+ IntrusionDetectionEvent eventOne = new IntrusionDetectionEvent(securityEvent);
+
+ ConnectEvent connectEvent = new ConnectEvent(
+ "127.0.0.1", 80, null, 0);
+ IntrusionDetectionEvent eventTwo = new IntrusionDetectionEvent(connectEvent);
+
+ DnsEvent dnsEvent = new DnsEvent(
+ null, new String[] {"127.0.0.1"}, 1, null, 0);
+ IntrusionDetectionEvent eventThree = new IntrusionDetectionEvent(dnsEvent);
+
+ List<IntrusionDetectionEvent> events = new ArrayList<>();
+ events.add(eventOne);
+ events.add(eventTwo);
+ events.add(eventThree);
+
+ doReturn(true).when(mIntrusionDetectionEventTransportConnection).addData(any());
+
+ mDataAggregator.addBatchData(events);
+ mTestLooperOfDataAggregator.dispatchAll();
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List<IntrusionDetectionEvent>> captor = ArgumentCaptor.forClass(List.class);
+ verify(mIntrusionDetectionEventTransportConnection).addData(captor.capture());
+ List<IntrusionDetectionEvent> receivedEvents = captor.getValue();
+ assertEquals(receivedEvents.size(), 3);
+
+ assertEquals(receivedEvents.get(0).getType(), IntrusionDetectionEvent.SECURITY_EVENT);
+ assertNotNull(receivedEvents.get(0).getSecurityEvent());
+
+ assertEquals(receivedEvents.get(1).getType(),
+ IntrusionDetectionEvent.NETWORK_EVENT_CONNECT);
+ assertNotNull(receivedEvents.get(1).getConnectEvent());
+
+ assertEquals(receivedEvents.get(2).getType(), IntrusionDetectionEvent.NETWORK_EVENT_DNS);
+ assertNotNull(receivedEvents.get(2).getDnsEvent());
+ }
+
+ private class MockInjector implements IntrusionDetectionService.Injector {
+ private final Context mContext;
+
+ MockInjector(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public Context getContext() {
+ return mContext;
+ }
+
+ @Override
+ public PermissionEnforcer getPermissionEnforcer() {
+ return mPermissionEnforcer;
+ }
+
+ @Override
+ public Looper getLooper() {
+ return mLooper;
+ }
+
+ @Override
+ public IntrusionDetectionEventTransportConnection
+ getIntrusionDetectionEventransportConnection() {
+ mIntrusionDetectionEventTransportConnection =
+ spy(new IntrusionDetectionEventTransportConnection(mContext));
+ return mIntrusionDetectionEventTransportConnection;
+ }
+
+ @Override
+ public DataAggregator getDataAggregator(
+ IntrusionDetectionService intrusionDetectionService) {
+ mDataAggregator = spy(new DataAggregator(mContext, intrusionDetectionService));
+ return mDataAggregator;
+ }
+ }
+
+ private static class StateCallback extends IIntrusionDetectionServiceStateCallback.Stub {
+ int mState = STATE_UNKNOWN;
+
+ @Override
+ public void onStateChange(int state) throws RemoteException {
+ mState = state;
+ }
+ }
+
+ private static class CommandCallback extends IIntrusionDetectionServiceCommandCallback.Stub {
+ Integer mErrorCode = null;
+
+ public void reset() {
+ mErrorCode = null;
+ }
+
+ @Override
+ public void onSuccess() throws RemoteException {
+
+ }
+
+ @Override
+ public void onFailure(int errorCode) throws RemoteException {
+ mErrorCode = errorCode;
+ }
+ }
+}