Loading services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java +73 −10 Original line number Diff line number Diff line Loading @@ -24,42 +24,56 @@ import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.security.intrusiondetection.IIntrusionDetectionEventTransport; import android.security.intrusiondetection.IntrusionDetectionEvent; import android.security.intrusiondetection.IIntrusionDetectionEventTransport; import android.text.TextUtils; import android.util.Slog; import com.android.internal.R; import com.android.internal.infra.AndroidFuture; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.lang.Process; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeUnit; public class IntrusionDetectionEventTransportConnection implements ServiceConnection { private static final String PRODUCTION_BUILD = "user"; private static final String PROPERTY_BUILD_TYPE = "ro.build.type"; private static final String PROPERTY_INTRUSION_DETECTION_SERVICE_NAME = "intrusiondetection_service_name"; private static final long FUTURE_TIMEOUT_MILLIS = 60 * 1000; // 1 min private static final String TAG = "IntrusionDetectionEventTransportConnection"; private static final long FUTURE_TIMEOUT_MILLIS = 60 * 1000; // 1 mins private final Context mContext; private String mIntrusionDetectionEventTransportConfig; volatile IIntrusionDetectionEventTransport mService; public IntrusionDetectionEventTransportConnection(Context context) { mContext = context; mService = null; } /** * Initialize the IntrusionDetectionEventTransport binder service. * @return Whether the initialization succeed. * * @return Whether the initialization succeeds. */ public boolean initialize() { Slog.d(TAG, "initialize"); if (!bindService()) { return false; } // Wait for the service to be connected before calling initialize. waitForConnection(); AndroidFuture<Boolean> resultFuture = new AndroidFuture<>(); try { mService.initialize(resultFuture); Loading @@ -77,6 +91,20 @@ public class IntrusionDetectionEventTransportConnection implements ServiceConnec } } private void waitForConnection() { synchronized (this) { while (mService == null) { Slog.d(TAG, "waiting for connection to service..."); try { this.wait(); } catch (InterruptedException e) { /* never interrupted */ } } Slog.d(TAG, "connected to service"); } } /** * Add data to the IntrusionDetectionEventTransport binder service. * @param data List of IntrusionDetectionEvent. Loading Loading @@ -118,11 +146,38 @@ public class IntrusionDetectionEventTransportConnection implements ServiceConnec } } private String getSystemPropertyValue(String propertyName) { String comamandString = "getprop " + propertyName; try { Process process = Runtime.getRuntime().exec(comamandString); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String propertyValue = reader.readLine(); reader.close(); return propertyValue; } catch (IOException e) { Slog.e(TAG, "Failed to get system property value:", e); return null; } } private boolean bindService() { mIntrusionDetectionEventTransportConfig = mContext.getString( String buildType = getSystemPropertyValue(PROPERTY_BUILD_TYPE); mIntrusionDetectionEventTransportConfig = mContext.getString( com.android.internal.R.string.config_intrusionDetectionEventTransport); // If the build type is not production, and a property value is set, use it instead. // This allows us to test the service with a different config. if (!buildType.equals(PRODUCTION_BUILD) && !TextUtils.isEmpty( getSystemPropertyValue(PROPERTY_INTRUSION_DETECTION_SERVICE_NAME))) { mIntrusionDetectionEventTransportConfig = getSystemPropertyValue(PROPERTY_INTRUSION_DETECTION_SERVICE_NAME); } if (TextUtils.isEmpty(mIntrusionDetectionEventTransportConfig)) { Slog.e(TAG, "config_intrusionDetectionEventTransport is empty"); Slog.e(TAG, "Unable to find a valid config for the transport service"); return false; } Loading Loading @@ -163,11 +218,19 @@ public class IntrusionDetectionEventTransportConnection implements ServiceConnec @Override public void onServiceConnected(ComponentName name, IBinder service) { synchronized (this) { mService = IIntrusionDetectionEventTransport.Stub.asInterface(service); Slog.d(TAG, "connected to service"); this.notifyAll(); } } @Override public void onServiceDisconnected(ComponentName name) { synchronized (this) { mService = null; Slog.d(TAG, "disconnected from service"); this.notifyAll(); } } } services/tests/security/intrusiondetection/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ <uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE" /> <application android:testOnly="true" android:debuggable="true" android:usesCleartextTraffic="true"> <uses-library android:name="android.test.runner"/> Loading services/tests/security/intrusiondetection/AndroidTest.xml +4 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ <option name="install-arg" value="-t" /> </target_preparer> <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> <option name="run-command" value="setprop intrusiondetection_service_name com.android.coretests.apps.testapp/.TestLoggingService" /> </target_preparer> <option name="test-tag" value="IntrusionDetectionServiceTests" /> <test class="com.android.tradefed.testtype.InstrumentationTest" > <option name="package" value="com.android.server.security.intrusiondetection.tests" /> Loading services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.security.intrusiondetection; import static android.Manifest.permission.INTERNET; import static android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE; import static android.Manifest.permission.READ_INTRUSION_DETECTION_STATE; import static android.Manifest.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading @@ -44,6 +45,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.Manifest; import android.os.IBinder; import android.os.Bundle; import android.os.Looper; Loading Loading @@ -159,6 +161,7 @@ public class IntrusionDetectionServiceTest { mPermissionEnforcer = new FakePermissionEnforcer(); mPermissionEnforcer.grant(READ_INTRUSION_DETECTION_STATE); mPermissionEnforcer.grant(MANAGE_INTRUSION_DETECTION_STATE); mPermissionEnforcer.grant(BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE); mTestLooper = new TestLooper(); mLooper = mTestLooper.getLooper(); Loading Loading @@ -578,6 +581,9 @@ public class IntrusionDetectionServiceTest { } @Test @RequireRunOnSystemUser @EnsureHasPermission( android.Manifest.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE) public void test_StartIntrusionDetectionEventTransportService() { final String TAG = "test_StartIntrusionDetectionEventTransportService"; ServiceConnection serviceConnection = null; Loading Loading @@ -639,6 +645,20 @@ public class IntrusionDetectionServiceTest { return serviceConnection; } @Test @RequireRunOnSystemUser @EnsureHasPermission( android.Manifest.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE) public void testIntrusionDetectionEventTransportConnection_isValidAndBinds() throws InterruptedException { IntrusionDetectionEventTransportConnection intrusionDetectionEventTransportConnection = new IntrusionDetectionEventTransportConnection(mContext); // In a real scenario, the connection will be initialized by the service. // Just to show that the connection is valid and able to bind, // we initialize it here. assertTrue(intrusionDetectionEventTransportConnection.initialize()); } private class MockInjector implements IntrusionDetectionService.Injector { private final Context mContext; Loading services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/AndroidManifest.xml +3 −1 Original line number Diff line number Diff line Loading @@ -16,9 +16,11 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.coretests.apps.testapp"> <uses-permission android:name="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE" /> <application> <service android:name=".TestLoggingService" android:exported="true" /> android:exported="true" android:permission="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE" /> </application> </manifest> No newline at end of file Loading
services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java +73 −10 Original line number Diff line number Diff line Loading @@ -24,42 +24,56 @@ import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.security.intrusiondetection.IIntrusionDetectionEventTransport; import android.security.intrusiondetection.IntrusionDetectionEvent; import android.security.intrusiondetection.IIntrusionDetectionEventTransport; import android.text.TextUtils; import android.util.Slog; import com.android.internal.R; import com.android.internal.infra.AndroidFuture; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.lang.Process; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeUnit; public class IntrusionDetectionEventTransportConnection implements ServiceConnection { private static final String PRODUCTION_BUILD = "user"; private static final String PROPERTY_BUILD_TYPE = "ro.build.type"; private static final String PROPERTY_INTRUSION_DETECTION_SERVICE_NAME = "intrusiondetection_service_name"; private static final long FUTURE_TIMEOUT_MILLIS = 60 * 1000; // 1 min private static final String TAG = "IntrusionDetectionEventTransportConnection"; private static final long FUTURE_TIMEOUT_MILLIS = 60 * 1000; // 1 mins private final Context mContext; private String mIntrusionDetectionEventTransportConfig; volatile IIntrusionDetectionEventTransport mService; public IntrusionDetectionEventTransportConnection(Context context) { mContext = context; mService = null; } /** * Initialize the IntrusionDetectionEventTransport binder service. * @return Whether the initialization succeed. * * @return Whether the initialization succeeds. */ public boolean initialize() { Slog.d(TAG, "initialize"); if (!bindService()) { return false; } // Wait for the service to be connected before calling initialize. waitForConnection(); AndroidFuture<Boolean> resultFuture = new AndroidFuture<>(); try { mService.initialize(resultFuture); Loading @@ -77,6 +91,20 @@ public class IntrusionDetectionEventTransportConnection implements ServiceConnec } } private void waitForConnection() { synchronized (this) { while (mService == null) { Slog.d(TAG, "waiting for connection to service..."); try { this.wait(); } catch (InterruptedException e) { /* never interrupted */ } } Slog.d(TAG, "connected to service"); } } /** * Add data to the IntrusionDetectionEventTransport binder service. * @param data List of IntrusionDetectionEvent. Loading Loading @@ -118,11 +146,38 @@ public class IntrusionDetectionEventTransportConnection implements ServiceConnec } } private String getSystemPropertyValue(String propertyName) { String comamandString = "getprop " + propertyName; try { Process process = Runtime.getRuntime().exec(comamandString); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String propertyValue = reader.readLine(); reader.close(); return propertyValue; } catch (IOException e) { Slog.e(TAG, "Failed to get system property value:", e); return null; } } private boolean bindService() { mIntrusionDetectionEventTransportConfig = mContext.getString( String buildType = getSystemPropertyValue(PROPERTY_BUILD_TYPE); mIntrusionDetectionEventTransportConfig = mContext.getString( com.android.internal.R.string.config_intrusionDetectionEventTransport); // If the build type is not production, and a property value is set, use it instead. // This allows us to test the service with a different config. if (!buildType.equals(PRODUCTION_BUILD) && !TextUtils.isEmpty( getSystemPropertyValue(PROPERTY_INTRUSION_DETECTION_SERVICE_NAME))) { mIntrusionDetectionEventTransportConfig = getSystemPropertyValue(PROPERTY_INTRUSION_DETECTION_SERVICE_NAME); } if (TextUtils.isEmpty(mIntrusionDetectionEventTransportConfig)) { Slog.e(TAG, "config_intrusionDetectionEventTransport is empty"); Slog.e(TAG, "Unable to find a valid config for the transport service"); return false; } Loading Loading @@ -163,11 +218,19 @@ public class IntrusionDetectionEventTransportConnection implements ServiceConnec @Override public void onServiceConnected(ComponentName name, IBinder service) { synchronized (this) { mService = IIntrusionDetectionEventTransport.Stub.asInterface(service); Slog.d(TAG, "connected to service"); this.notifyAll(); } } @Override public void onServiceDisconnected(ComponentName name) { synchronized (this) { mService = null; Slog.d(TAG, "disconnected from service"); this.notifyAll(); } } }
services/tests/security/intrusiondetection/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ <uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE" /> <application android:testOnly="true" android:debuggable="true" android:usesCleartextTraffic="true"> <uses-library android:name="android.test.runner"/> Loading
services/tests/security/intrusiondetection/AndroidTest.xml +4 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ <option name="install-arg" value="-t" /> </target_preparer> <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> <option name="run-command" value="setprop intrusiondetection_service_name com.android.coretests.apps.testapp/.TestLoggingService" /> </target_preparer> <option name="test-tag" value="IntrusionDetectionServiceTests" /> <test class="com.android.tradefed.testtype.InstrumentationTest" > <option name="package" value="com.android.server.security.intrusiondetection.tests" /> Loading
services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.security.intrusiondetection; import static android.Manifest.permission.INTERNET; import static android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE; import static android.Manifest.permission.READ_INTRUSION_DETECTION_STATE; import static android.Manifest.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading @@ -44,6 +45,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.Manifest; import android.os.IBinder; import android.os.Bundle; import android.os.Looper; Loading Loading @@ -159,6 +161,7 @@ public class IntrusionDetectionServiceTest { mPermissionEnforcer = new FakePermissionEnforcer(); mPermissionEnforcer.grant(READ_INTRUSION_DETECTION_STATE); mPermissionEnforcer.grant(MANAGE_INTRUSION_DETECTION_STATE); mPermissionEnforcer.grant(BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE); mTestLooper = new TestLooper(); mLooper = mTestLooper.getLooper(); Loading Loading @@ -578,6 +581,9 @@ public class IntrusionDetectionServiceTest { } @Test @RequireRunOnSystemUser @EnsureHasPermission( android.Manifest.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE) public void test_StartIntrusionDetectionEventTransportService() { final String TAG = "test_StartIntrusionDetectionEventTransportService"; ServiceConnection serviceConnection = null; Loading Loading @@ -639,6 +645,20 @@ public class IntrusionDetectionServiceTest { return serviceConnection; } @Test @RequireRunOnSystemUser @EnsureHasPermission( android.Manifest.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE) public void testIntrusionDetectionEventTransportConnection_isValidAndBinds() throws InterruptedException { IntrusionDetectionEventTransportConnection intrusionDetectionEventTransportConnection = new IntrusionDetectionEventTransportConnection(mContext); // In a real scenario, the connection will be initialized by the service. // Just to show that the connection is valid and able to bind, // we initialize it here. assertTrue(intrusionDetectionEventTransportConnection.initialize()); } private class MockInjector implements IntrusionDetectionService.Injector { private final Context mContext; Loading
services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/AndroidManifest.xml +3 −1 Original line number Diff line number Diff line Loading @@ -16,9 +16,11 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.coretests.apps.testapp"> <uses-permission android:name="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE" /> <application> <service android:name=".TestLoggingService" android:exported="true" /> android:exported="true" android:permission="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE" /> </application> </manifest> No newline at end of file