function updateIcons()

in lib/prepare.js [682:757]


function updateIcons (cordovaProject, platformResourcesDir) {
    const icons = cordovaProject.projectConfig.getIcons('android');

    // Skip if there are no app defined icons in config.xml
    if (icons.length === 0) {
        events.emit('verbose', 'This app does not have launcher icons defined');
        return;
    }

    // 1. loop icons determin if there is an error in the setup.
    // 2. during initial loop, also setup for legacy support.
    const errorMissingAttributes = [];
    const errorLegacyIconNeeded = [];
    let hasAdaptive = false;
    icons.forEach((icon, key) => {
        if (
            (icon.background && !icon.foreground) ||
            (!icon.background && icon.foreground) ||
            (!icon.background && !icon.foreground && !icon.src)
        ) {
            errorMissingAttributes.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));
        }

        if (icon.foreground) {
            hasAdaptive = true;

            if (
                !icon.src &&
                (
                    icon.foreground.startsWith('@color') ||
                    path.extname(path.basename(icon.foreground)) === '.xml'
                )
            ) {
                errorLegacyIconNeeded.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));
            } else if (!icon.src) {
                icons[key].src = icon.foreground;
            }
        }
    });

    const errorMessage = [];
    if (errorMissingAttributes.length > 0) {
        errorMessage.push('One of the following attributes are set but missing the other for the density type: ' + errorMissingAttributes.join(', ') + '. Please ensure that all require attributes are defined.');
    }

    if (errorLegacyIconNeeded.length > 0) {
        errorMessage.push('For the following icons with the density of: ' + errorLegacyIconNeeded.join(', ') + ', adaptive foreground with a defined color or vector can not be used as a standard fallback icon for older Android devices. To support older Android environments, please provide a value for the src attribute.');
    }

    if (errorMessage.length > 0) {
        throw new CordovaError(errorMessage.join(' '));
    }

    let resourceMap = Object.assign(
        {},
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.png'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.xml'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
    );

    const preparedIcons = prepareIcons(icons);

    if (hasAdaptive) {
        resourceMap = updateIconResourceForAdaptive(preparedIcons, resourceMap, platformResourcesDir);
    }

    resourceMap = updateIconResourceForLegacy(preparedIcons, resourceMap, platformResourcesDir);

    events.emit('verbose', 'Updating icons at ' + platformResourcesDir);
    FileUpdater.updatePaths(resourceMap, { rootDir: cordovaProject.root }, logFileOp);
}