Search code examples
androidservice

On Android 11 Remote Bound Service binding fails when invoked from Client app


On Android 11 Remote bound Service binding fails when invoked from Client app

Problem is specific to Android 11 only.

1: Using remote bound service with AIDL interface. This service is derived from service B, which is also using AIDL interface.

public class IPCEnterpriseServicePcsc extends IPCServicePcsc {
    ...
    protected IPCEnterpriseInterfaceLicense licenseBinder;
    ...
}

public class IPCEnterpriseInterfaceLicense extends IRemotePcscServiceLicense.Stub {...}

public class IPCServicePcsc extends IPCService {
        ...
    protected IPCInterfacePcsc mBinder;
    ...
}

public class IPCInterfacePcsc extends IRemotePcscService.Stub{...}

2. Below is the Manifest of server application defining the service:

    <service android:label="@string/pcsc_service_name" android:name=".IPCEnterpriseServicePcsc" >
        <intent-filter>
            <action android:name="com.baimobile.android.enterprise.credential.service.ipc.action.BIND_PCSC" />
            <action android:name="com.baimobile.android.enterprise.credential.service.ipc.action.BIND_LICENSE" />
            <action android:name="com.baimobile.android.enterprise.credential.service.license.action.VALIDATE_USER_LICENSE_INFO" />
        </intent-filter>
    </service>

server app id is "com.baimobile.android.enterprise.credential.service"

3.1 From a client app, Service 'IPCEnterpriseServicePcsc' is invoked as below:

Intent intent = new Intent("com.baimobile.android.enterprise.credential.service.ipc.action.BIND_LICENSE"); intent.setPackage("com.baimobile.android.enterprise.credential.service"); intent.putExtra("Interface","IRemotePcscServiceLicense");

boolean pcscServiceInstalled = appContext.bindService(intent, connectionToPcscInterface, Context.BIND_AUTO_CREATE);

3.2: connectionToPcscInterface is defined as:

private ServiceConnection connectionToPcscInterface = new ServiceConnection() {
    public void onServiceConnected(ComponentName remoteComponent, IBinder binder) {...};
    public void onServiceDisconnected(ComponentName arg0) {..};
}

3.3: With successful appContext.bindService()in step 3.1, onServiceConnected() mentoned in Step 3.2 is invoked by service. Here we are doing some validation and then binding to base class service IPCServicePcsc

    Intent intent = new Intent("com.baimobile.android.pcsclite.service.ipc.action.BIND_PCSC");
    intent.setPackage("com.baimobile.android.enterprise.credential.service");
    intent.putExtra("Interface","IRemotePcscService");          // Request the PC/SC interface instead of the license interface.
    pcscServiceInstalled = appContext.bindService(intent, connectionToPcscInterface, Context.BIND_AUTO_CREATE);
    if( ! pcscServiceInstalled ){
        Log.e("TAG","bindService failed.");
    }

Problem Statement: Till Android 10, client application is able to connect with these services very well however on Android 11, binding under Step 3.3 fails.

Any idea what could be the problem and looking for suggestions to troubleshoot it. Seems something broken or hardened on Android 11.


Solution

  • If you have not done so already, your client app needs a <queries> element in the manifest to identify the service app.

    For example, in this client app, I have:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.commonsware.android.r.embed.client">
      <queries>
        <package android:name="com.commonsware.android.r.embed.server" />
      </queries>
    
      <application
        android:name=".MainApp"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
          <intent-filter>
            <action android:name="android.intent.action.MAIN" />
    
            <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
        </activity>
      </application>
    
    </manifest>
    

    That <queries> element identifies the package of a separate app that has a bound service that the client app binds to.