com.atlassian.confluence.content.render.xhtml.migration.exceptions.UnknownMacroMigrationException: The macro 'next_previous_link3' is unknown.

White Labeling WSO2 EMM Android App Catalog

Prerequisites 

  1. Download and install Android Studio.

    For more information, see installing Android Studio.

  2. WSO2 EMM supports API levels 16 to 23. Therefore install the Android API levels 16 to 23 on Android Studio.
    1. Open Android Studio.
    2. Click SDK Manager.
    3. Click the SDK Platform tab and select the 16 and 23 API levels.
    4. Click Apply.

Changing Android app catalog related logos and icons

  1. Clone the product-emm repository. The folder will be referred to as <PRODUCT_EMM> throughout the documentation.

     git clone https://github.com/wso2/product-emm
  2. Navigate to the <APP_CATALOG>/app/src/main/res directory.

    <APP_CATALOG> refers to the <PRODUCT_EMM>/modules/mobile-agents/android/appcatalog file path.

    1. Navigate to the mipmap-xxhdpi/ folder and change the ic_launcher.png ( 144px X 144px ) file in order to change the icon. For more information, go to the Android icon guide.
    2. Navigate to the mipmap-xxhdpi/ folder, and change the following file logos in order to change the header logos:

      ic_logo.png  ( 240px X 72px )
      repeat_bg.png   ( 277px X 125px )
    3. Navigate to the mipmap -xhdpi/ folder, and change the ic_launcher.png ( 96px X 96px ) file to change the application icon.
    4. Navigate to the  drawable-xhdpi/ folder, and change  the ic_logo.png (267px X 48px), and repeat_bg.png (222px X 100px) file in order to change the logos.
    5. Navigate to the mipmap-hdpi/ folder, and change the ic_launcher.png (72px X 72px) file in order to change the icon.

    6. Navigate to the drawable-hdpi/ folder, and change the ic_logo.png (200px X 36px), and repeat_bg.png (122px X 55px) files in order to change the logos.

    7. Navigate to the mipmap-mdpi/ folder, and change the ic_launcher.png (48px X 48px) file to change the icon.

    8. Navigate to the drawable-mdpi/ folder, and change the ic_logo.png (133px X 24px) file in order to change the logos.

  3. Open the app-catalog folder that is in the <EMM_SOURCE_HOME>/modules/mobile-agent/android directory via Android Studio.
  4. Build the project to create a new APK with the changes.

     Click here for more information on building the project.

    Support for the Android Developer Tools (ADT) in Eclipse is ending. Therefore, you should migrate the app development projects to Android Studio. For more information on transitioning to Android Studio, see Migrating to Android Studio.

    1. Get a GIT clone of the Android Agent application from GitHub.

    2. Update the Android Software Development Kit with the following:

      • SDK Versions 23 and 16. 

      • Build Tools Version 22.0.1.

      • Install or update Android Support Library.

      • Install or update Google Play Services.

      • Install Google USB Driver, if you are on a Windows platform.

    3. By default, the Android agent communicates with the server through http. For production, this needs to be changed to https, by configuring the following parameters in the Java class named Constants.java, which is in the org.wso2.EMM.agent.utils package: SERVER_PORT and SERVER_PROTOCOL.

      For more information see below:

       Generating a BKS File

      The Android agent must have the CA certificate inside the application when configuring the Secure Sockets Layer (SSL). The CA certificate is stored in a BKS (bouncycastle) file. Follow the steps given below to create and generate a BKS file: 

      Prerequisites 

      Step 1: Creating a BKS file

      If you configured EMM for iOS, you can skip this step and move to Step 2 by using the already generated and imported Certificate Authority (CA), Registration Authority (RA), and SSL certificate files.

      1. Navigate to the openssl.cnf file of the OpenSSL installation. 

      2. Make a copy of the  openssl.cnf  file, move it to another location, and configure the file to generate version 3 certificates as shown below:

        [ v3_req ] 
        # Extensions to add to a certificate request 
        basicConstraints=CA:TRUE 
        keyUsage = Digital Signature, Key Encipherment 
        
        [ v3_ca ] 
        # Extensions for a typical CA 
        # PKIX recommendation. 
        subjectKeyIdentifier=hash 
        authorityKeyIdentifier=keyid:always,issuer 
        # This is what PKIX recommends but some broken software chokes on critical 
        # extensions. 
        basicConstraints = critical,CA:true 
        # So we do this instead. 
        #basicConstraints = CA:true 
        # Key usage: this is typical for a CA certificate. However since it will 
        # prevent it being used as an test self-signed certificate it is best 
        # left out by default. 
        keyUsage = Digital Signature, Certificate Sign, CRL Sign
      3. In the location where you modified and saved the openssl.cnf file, run the following commands to generate a self-signed Certificate Authority (CA) certificate (version 3) and convert the certificate to the .pem format:

        1. openssl genrsa -out <CA PRIVATE KEY> 4096
          For example: openssl genrsa -out ca_private.key 4096
        2. openssl req -new -key <CA PRIVATE KEY> -out <CA CSR>
          For example: openssl req -new -key ca_private.key -out ca.csr
        3. openssl x509 -req -days <DAYS> -in <CA CSR> -signkey <CA PRIVATE KEY> -out <CA CRT> -extensions v3_ca -extfile <PATH-TO-MODIFIED-openssl.cnf-FILE>
          For example: openssl x509 -req -days 365 -in ca.csr -signkey ca_private.key -out ca.crt -extensions v3_ca -extfile ./openssl.cnf
        4. openssl rsa -in <CA PRIVATE KEY> -text > <CA PRIVATE PEM>
          For example:  openssl rsa -in ca_private.key -text > ca_private.pem
        5. openssl x509 -in <CA CRT> -out <CA CERT PEM>
          For example: openssl x509 -in ca.crt -out ca_cert.pem
      4. In the same location, run the following commands to generate a Registration Authority (RA) certificate (version 3), sign it with the CA, and convert the certificate to the .pem  format. 

        1. openssl genrsa -out <RA PRIVATE KEY> 4096
          For example:  openssl genrsa -out ra_private.key 4096

        2. openssl req -new -key <RA PRIVATE KEY> -out <RA CSR>
          For example: openssl req -new -key ra_private.key -out ra.csr
        3. openssl x509 -req -days <DAYS> -in <RA CSR> -CA <CA CRT> -CAkey <CA PRIVATE KEY> -set_serial <SERIAL NO> -out <RA CRT> -extensions v3_req -extfile <PATH-TO-MODIFIED- openssl.cnf-FILE >
          For example: openssl x509 -req -days 365 -in ra.csr -CA ca.crt -CAkey ca_private.key -set_serial 02 -out ra.crt -extensions v3_req -extfile ./openssl.cnf
        4. openssl rsa -in <CA PRIVATE KEY> -text > <RA PRIVATE PEM>
          For example: openssl rsa -in ra_private.key -text > ra_private.pem
        5. openssl x509 -in <RA CRT> -out <RA CERT PEM>
          For example: openssl x509 -in ra.crt -out ra_cert.pem
      5. Generate the SSL certificate (version 3) based on your domain/IP address:

        You must add your IP address/domain as the Common Name. Otherwise, provisioning will fail. 

        1. Generate an RSA key.
          openssl genrsa -out <RSA_key>.key 4096
          For example:
          openssl genrsa -out ia.key 4096
        2. Generate a CSR file.
          openssl req -new -key <RSA_key>.key -out <CSR>.csr
          For example:
          openssl req -new -key ia.key -out ia.csr
          Enter your server IP address/domain name (e.g., 192.168.1.157) as the Common Name else provisioning will fail.
        3. Generate the SSL certificate.
          openssl x509 -req -days 730 -in <CSR>.csr -CA ca_cert.pem -CAkey ca_private.pem -set_serial <serial number> -out ia.crt
          For example: 
          openssl x509 -req -days 730 -in ia.csr -CA ca_cert.pem -CAkey ca_private.pem -set_serial 044324343 -out ia.crt
      6. Export the SSL, CA, and RA files as PKCS12 files with an alias.

        1. Export the SSL file as a PKCS12 file with "wso2carbon" as the alias. 
          openssl pkcs12 -export -out <KEYSTORE>.p12 -inkey <RSA_key>.key -in ia.crt -CAfile ca_cert.pem -name "<alias>"
          For example:
          openssl pkcs12 -export -out KEYSTORE.p12 -inkey ia.key -in ia.crt -CAfile ca_cert.pem -name "wso2carbon"

        2. Export the CA file as a PKCS12 file with an alias.
          openssl pkcs12 -export -out <CA>.p12 -inkey <CA private key>.pem -in <CA Cert>.pem -name "<alias>"
          For example:
          openssl pkcs12 -export -out ca.p12 -inkey ca_private.pem -in ca_cert.pem -name "cacert"
          In the above example, cacert has been used as the CA alias. 
        3. Export the RA file as a PKCS12 file with an alias.
          openssl pkcs12 -export -out <RA>.p12 -inkey <RA private key>.pem -in <RA Cert>.pem -chain -CAfile <CA cert>.pem -name "<alias>"
          For example:
          openssl pkcs12 -export -out ra.p12 -inkey ra_private.pem -in ra_cert.pem -chain -CAfile ca_cert.pem -name "racert"
          In the above example, racert has been used as the RA alias. 
      7. Copy the three P12 files to the <EMM_HOME>/repository/resources/security directory.
      8. Import the generated P12 files as follows:
        1. Import the generated <KEYSTORE>.p12 file into the wso2carbon.jks and client-truststore.jks in the <EMM_HOME>/repository/resources/security directory.
          keytool -importkeystore -srckeystore <KEYSTORE>.p12 -srcstoretype PKCS12 -destkeystore <wso2carbon.jks/client-truststore.jks>

          When prompted, enter the keystore password and keystore key password as wso2carbon.

          For example:
          keytool -importkeystore -srckeystore KEYSTORE.p12 -srcstoretype PKCS12 -destkeystore wso2carbon.jks
          keytool -importkeystore -srckeystore KEYSTORE.p12 -srcstoretype PKCS12 -destkeystore client-truststore.jks

        2. Import the generated <CA>.p12 and <RA>.p12 files into the wso2certs.jks file, which is in the <EMM_HOME>/repository/resources/security directory.
          keytool -importkeystore -srckeystore <CA/RA>.p12 -srcstoretype PKCS12 -destkeystore wso2emm.jks

          For example:
          keytool -importkeystore -srckeystore ca.p12 -srcstoretype PKCS12 -destkeystore wso2certs.jks 
          Enter the keystore password as wso2carbon and keystore key password as cacert.

          keytool -importkeystore -srckeystore ra.p12 -srcstoretype PKCS12 -destkeystore wso2certs.jks 
          Enter the keystore password as  wso2carbon  and keystore key password as racert.

          Troubleshooting

          Why does the following error occur: " keytool error: java.io.IOException: Invalid keystore format"?

          If you enter the wrong private key password when importing the <CA>.p12 or <RA>.p12 files, the wso2certs.jks file will get corrupted and the above error message will appear.

          In such a situation, delete the wso2certs.jks file and execute the following command to import the generated <CA>.p12 and <RA>.p12 files into the wso2certs.jks file again.
          keytool -importkeystore -srckeystore <CA/RA>.p12 -srcstoretype PKCS12 -destkeystore wso2certs.jks

          When the above command is executed, EMM will automatically create a new wso2certs.jks file with the imported file.

      Step 2: Generating a BKS file

      Follow all the steps given under step 1 before generating the BKS file to avoid errors.

      1. Generate the BKS file:

        Ensure that you have the bcprov-jdk16-1.46.jar file in the same folder where you will be generating the BKS file before you run this command.

        keytool -noprompt -import -v -trustcacerts -alias 'openssl x509 -inform PEM -subject_hash -noout -in ca_cert.pem' -file ca_cert.pem -keystore truststore.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk16-1.46.jar -storepass 'wso2carbon'

        If you are using an SSL certificate by a trusted authority such as GoDaddy, the cert.crt defined in the command should be the interim certificate. 
        Example:

        keytool -noprompt -import -v -trustcacerts -alias godaddy -file cert.crt -keystore truststore.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk16-1.46.jar -storepass 'wso2carbon'
      2. Optionally, view the list of certificates in the BKS form using the following command:

        keytool -list -v -keystore "truststore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-1.46.jar" -storetype BKS -storepass "wso2carbon"
      3. Copy the generated truststore.bks file to the <EMM_SOURCE_HOME>/modules/mobile-agents/android/client/iDPProxy/src/main/res/raw directory and replace the original file. 
      4. Navigate to the <EMMM_SOURCE_HOME>/modules/mobile-agents/android/client/client/src/main/java/org/wso2/emm/agent/utils/Constants.java file, and configure the following:
        • Provide the HTTPS_HOST_IP as the value for the SERVER_PORT parameter.
          Example: 9443.
        • Change the SERVER_PROTOCOL to https://.
        • Provide the BKS file password as the value for the TRUSTSTORE_PASSWORD parameter.
        Sample
        	public static boolean DEBUG_MODE_ENABLED = false;
        	public static boolean LOCAL_NOTIFICATIONS_ENABLED = true;
        	public static boolean GCM_ENABLED = false;
        
        	public static String SERVER_IP = "";
        
        	public static String SERVER_PORT = "9443";
        	public static String SERVER_PROTOCOL = "https://";
        	public static String API_VERSION = "1.0.0";
        	
        	public static String SERVER_APP_ENDPOINT = "/EMM/api/";
        
        	public static String OAUTH_ENDPOINT = "/oauth2/token";
        	public static String SENDER_ID_ENDPOINT = "devices/sender_id/";
        	public static String IS_REGISTERED_ENDPOINT = "devices/isregistered/";
        	public static String LICENSE_ENDPOINT = "devices/license/";
        	public static String REGISTER_ENDPOINT = "devices/register/";
        	public static String UNREGISTER_ENDPOINT = "devices/unregister/";
        	public static String NOTIFICATION_ENDPOINT = "notifications/pendingOperations/";
        	
        	public static String SERVER_URL = SERVER_PROTOCOL + SERVER_IP + ":"
        			+ SERVER_PORT + SERVER_APP_ENDPOINT;
        
        	public static final String TRUSTSTORE_PASSWORD = "<BKS_FILE_PASSWORD>";
        	public static final String EULA_TITLE = "POLICY AGREEMENT";
      5. Navigate to the <EMMM_SOURCE_HOME>/modules/mobile-agents/android/client/iDPProxy/src/main/java/org/wso2/emm/agent/proxy/utils/Constants.java file, and configure the SERVER_PROTOCOL as https://.

    4. Import the project on Android Studio, clean and build the project.

    5. Run the project on a device.

      The .apk file can be found in the <EMM_HOME>/repository/deployment/server/jaggeryapps/emm-web-agent/units/asset-download-agent-android/public/asset directory.

  5. Publish the built APK to your app store via the WSO2 App Manager publisher.

    For more information, see Creating an Android Application.

com.atlassian.confluence.content.render.xhtml.migration.exceptions.UnknownMacroMigrationException: The macro 'next_previous_links2' is unknown.