1

I want to use the demo application TestDPC released by Google to create a Work Profile with my own device policy controller so I added some code to this app in order to connect to GCM service to receive cloud messages to start some actions on my device.
To connect to GCM I used some example code that I tested separately and it works, the only thing I added is a boot listener (ReceiverStarter) in order to activate GCM listener everytime the user reboot his device.
The strange thing is that when I install my app on device (Samsung Note 4 with Android 5.1.1 API 22) without create a managed profile the GCM client works properly.
If with the app early installed I create a work profile and the app itslef take control over the new profile the same code for GCM doesn't work anymore. I can see (using notifications) that in this case my dpc app can register to GCM and fetch GCM ID and I can read it in my console but the listener (MyGcmListenerService) doesn't receive any cloud messages as if the listener is not up and running, I cannot see any errors and/or logs in my console.
Maybe I need some more permissions?
Here my manifest

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<permission android:name="com.xxx.emmagent.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.xxx.emmagent.permission.C2D_MESSAGE" />

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme"
        android:label="@string/app_name">

    <activity
        android:name=".LaunchActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

    <activity
        android:name=".gcm.MainActivity"
        android:label="@string/app_name"
        android:theme="@style/SetupTheme"/>

    <activity
            android:name=".PolicyManagementActivity"
            android:label="@string/app_name"
            android:windowSoftInputMode="adjustPan"/>

    <activity
            android:name=".AddAccountActivity"
            android:label="@string/app_name"
            android:theme="@style/SetupTheme"/>

    <activity
            android:name=".EnableProfileActivity"
            android:label="@string/app_name"
            android:theme="@style/SetupTheme"/>

    <activity
            android:name=".EnableDeviceOwnerActivity"
            android:label="@string/app_name"
            android:theme="@style/SetupTheme"/>

    <activity
            android:name=".cosu.EnableCosuActivity"
            android:label="@string/app_name"
            android:theme="@style/SetupTheme"/>

    <activity
            android:name=".syncauth.SetupSyncAuthManagement"
            android:label="@string/app_name"
            android:theme="@style/SetupTheme"/>

    <activity
            android:name=".syncauth.FinishSyncAuthDeviceOwnerActivity"
            android:label="@string/app_name"
            android:theme="@style/SetupTheme"/>

    <activity
            android:name=".syncauth.FinishSyncAuthProfileOwnerActivity"
            android:label="@string/app_name"
            android:theme="@style/SetupTheme"/>

    <activity
            android:name=".policy.locktask.KioskModeActivity"
            android:label="@string/kiosk_mode"
            android:launchMode="singleInstance"
            android:lockTaskMode="if_whitelisted"
            android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.HOME"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>

    <receiver
            android:name=".DeviceAdminReceiver"
            android:description="@string/app_name"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_DEVICE_ADMIN">
        <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/device_admin_receiver"/>
        <intent-filter>
            <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
            <action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE"/>
        </intent-filter>
    </receiver>

    <provider
            android:authorities="com.xxx.emmagent.fileprovider"
            android:name="android.support.v4.content.FileProvider"
            android:grantUriPermissions="true"
            android:exported="false">
        <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
    </provider>


    <!-- GCM messagging -->
    <!-- [START gcm_receiver] -->
    <receiver
        android:name="com.google.android.gms.gcm.GcmReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="com.xxx.emmagent" />
        </intent-filter>
    </receiver>
    <!-- [END gcm_receiver] -->

    <!-- [START gcm_listener] -->
    <service
        android:name=".gcm.MyGcmListenerService"
        android:exported="true" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>
    <!-- [END gcm_listener] -->
    <!-- [START instanceId_listener] -->
    <service
        android:name=".gcm.MyInstanceIDListenerService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.gms.iid.InstanceID"/>
        </intent-filter>
    </service>
    <!-- [END instanceId_listener] -->
    <service
        android:name=".gcm.RegistrationIntentService"
        android:exported="false">
    </service>

    <receiver android:name=".gcm.ReceiverStarter" android:enabled="true" android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>

</application>

I don't think it depends by code, as I said the same app and the same code without a work profile works well.
Any ideas?
Thanks in advance

EDIT: here the same problem

Community
  • 1
  • 1
zoro
  • 21
  • 3
  • I just want to clarify your question, based on my understanding, the problem is that the listener doesn't receive any messages when in idle state? and what is the relation of DPC and GCM? – Android Enthusiast Feb 08 '16 at 01:53
  • @d.datul1990: Hi, I try to clarify the problem: the problem is that the listener doesn't receive any messages when in idle state? Yes, but not only in idle state, the app can't receive any message in any state. what is the relation of DPC and GCM? I think there is a relation because the same code works if I don't use it in a DPC app for 'Android for Work' – zoro Feb 08 '16 at 14:10
  • Unfortunately I can't say 'how' but I have fixed this problem...I think is only GCM's configuration problem. **Now I can receive GCM message even in the managed profile** without any problems. Sorry I can't say more. – zoro Apr 04 '17 at 09:08

1 Answers1

0

according my knowledge the OS avoid triggering any managed profile intents from the personal profile as well (unless grant privileges). So although the request is reserved to the device from GCM, the device is unable to trigger your app's activities when the app is in the managed profile.

What you have to do is keep a separate unit in the personal profile which handles receiving GCM operations. You can grant privileges to certain intents to be cross share to the managed profile. In that way you can send the trigger though an intent to the app in the managed profile with relevant information to the operation. Let me know if it is not clear.

Please go through this link (Ensuring Compatibility with Managed Profiles) to understand enabling cross profile intents.

PasinduJay
  • 487
  • 5
  • 17
  • Thanks Pasindu, I don't understand very well why in a managed profile I can't receive a cloud message even if I understand is due a security constraint. Your solution is clear to me, actually I already have tested something like that configuring a cross intent from unmanaged profile to managed profile, but I hoped to do all in one app in my managed profile,I'll do some other tests and I'll write to you again. Thanks – zoro Apr 10 '16 at 16:25
  • great! Share with us the results, it might be useful for lot of people since this Android For Work is very new. – PasinduJay Apr 11 '16 at 06:11
  • Unfortunately I can't say 'how' but I have fixed this problem...I think is only GCM's configuration problem. **Now I can receive GCM message even in the managed profile** without any problems. Sorry I can't say more. – zoro Apr 04 '17 at 09:05