From 22bb8447b8f5852e61153f9373e616407311098f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=82=A8=E3=83=AA=E3=82=B9?= Date: Tue, 5 Jun 2018 13:43:05 +0900 Subject: [PATCH] CB-13685 android: Adaptive Icon Support - Update default project template's icons to be adaptive. - Added backwards support for non-adaptive icon supported devices. --- bin/templates/cordova/lib/prepare.js | 274 ++++++- bin/templates/project/AndroidManifest.xml | 2 +- .../res/mipmap-hdpi-v26/ic_launcher.xml | 5 + .../ic_launcher_background.png | Bin 0 -> 14629 bytes .../ic_launcher_foreground.png} | Bin .../project/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3345 bytes .../res/mipmap-ldpi-v26/ic_launcher.xml | 5 + .../ic_launcher_background.png | Bin 0 -> 14566 bytes .../ic_launcher_foreground.png | Bin 0 -> 1754 bytes .../mipmap-ldpi/{icon.png => ic_launcher.png} | Bin .../res/mipmap-mdpi-v26/ic_launcher.xml | 5 + .../ic_launcher_background.png | Bin 0 -> 14582 bytes .../ic_launcher_foreground.png | Bin 0 -> 2514 bytes .../mipmap-mdpi/{icon.png => ic_launcher.png} | Bin .../res/mipmap-xhdpi-v26/ic_launcher.xml | 5 + .../ic_launcher_background.png | Bin 0 -> 688 bytes .../ic_launcher_foreground.png | Bin 0 -> 11817 bytes .../{icon.png => ic_launcher.png} | Bin .../res/mipmap-xxhdpi-v26/ic_launcher.xml | 5 + .../ic_launcher_background.png | Bin 0 -> 1051 bytes .../ic_launcher_foreground.png | Bin 0 -> 23927 bytes .../{icon.png => ic_launcher.png} | Bin .../res/mipmap-xxxhdpi-v26/ic_launcher.xml | 5 + .../ic_launcher_background.png | Bin 0 -> 1390 bytes .../ic_launcher_foreground.png | Bin 0 -> 37563 bytes .../{icon.png => ic_launcher.png} | Bin spec/unit/prepare.spec.js | 757 ++++++++++++++++++ 27 files changed, 1030 insertions(+), 33 deletions(-) create mode 100644 bin/templates/project/res/mipmap-hdpi-v26/ic_launcher.xml create mode 100644 bin/templates/project/res/mipmap-hdpi-v26/ic_launcher_background.png rename bin/templates/project/res/{mipmap-hdpi/icon.png => mipmap-hdpi-v26/ic_launcher_foreground.png} (100%) create mode 100644 bin/templates/project/res/mipmap-hdpi/ic_launcher.png create mode 100644 bin/templates/project/res/mipmap-ldpi-v26/ic_launcher.xml create mode 100644 bin/templates/project/res/mipmap-ldpi-v26/ic_launcher_background.png create mode 100644 bin/templates/project/res/mipmap-ldpi-v26/ic_launcher_foreground.png rename bin/templates/project/res/mipmap-ldpi/{icon.png => ic_launcher.png} (100%) create mode 100644 bin/templates/project/res/mipmap-mdpi-v26/ic_launcher.xml create mode 100644 bin/templates/project/res/mipmap-mdpi-v26/ic_launcher_background.png create mode 100644 bin/templates/project/res/mipmap-mdpi-v26/ic_launcher_foreground.png rename bin/templates/project/res/mipmap-mdpi/{icon.png => ic_launcher.png} (100%) create mode 100644 bin/templates/project/res/mipmap-xhdpi-v26/ic_launcher.xml create mode 100644 bin/templates/project/res/mipmap-xhdpi-v26/ic_launcher_background.png create mode 100644 bin/templates/project/res/mipmap-xhdpi-v26/ic_launcher_foreground.png rename bin/templates/project/res/mipmap-xhdpi/{icon.png => ic_launcher.png} (100%) create mode 100644 bin/templates/project/res/mipmap-xxhdpi-v26/ic_launcher.xml create mode 100644 bin/templates/project/res/mipmap-xxhdpi-v26/ic_launcher_background.png create mode 100644 bin/templates/project/res/mipmap-xxhdpi-v26/ic_launcher_foreground.png rename bin/templates/project/res/mipmap-xxhdpi/{icon.png => ic_launcher.png} (100%) create mode 100644 bin/templates/project/res/mipmap-xxxhdpi-v26/ic_launcher.xml create mode 100644 bin/templates/project/res/mipmap-xxxhdpi-v26/ic_launcher_background.png create mode 100644 bin/templates/project/res/mipmap-xxxhdpi-v26/ic_launcher_foreground.png rename bin/templates/project/res/mipmap-xxxhdpi/{icon.png => ic_launcher.png} (100%) create mode 100644 spec/unit/prepare.spec.js diff --git a/bin/templates/cordova/lib/prepare.js b/bin/templates/cordova/lib/prepare.js index ac63f8a685..9dc85ff3af 100644 --- a/bin/templates/cordova/lib/prepare.js +++ b/bin/templates/cordova/lib/prepare.js @@ -265,6 +265,14 @@ function getImageResourcePath (resourcesDir, type, density, name, sourceName) { return resourcePath; } +function getAdaptiveImageResourcePath (resourcesDir, type, density, name, sourceName) { + if (/\.9\.png$/.test(sourceName)) { + name = name.replace(/\.png$/, '.9.png'); + } + var resourcePath = path.join(resourcesDir, (density ? type + '-' + density + '-v26' : type), name); + return resourcePath; +} + function updateSplashes (cordovaProject, platformResourcesDir) { var resources = cordovaProject.projectConfig.getSplashScreens('android'); @@ -314,20 +322,197 @@ function cleanSplashes (projectRoot, projectConfig, platformResourcesDir) { } function updateIcons (cordovaProject, platformResourcesDir) { - var icons = cordovaProject.projectConfig.getIcons('android'); + let icons = cordovaProject.projectConfig.getIcons('android'); - // if there are icon elements in config.xml + // 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; } - var resourceMap = mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'icon.png'); + // 1. loop icons determin if there is an error in the setup. + // 2. during initial loop, also setup for legacy support. + let errorMissingAttributes = []; + let 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; + } + } + }); - var android_icons = {}; - var default_icon; + let 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_foreground.xml'), + mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'), + mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.xml') + ); + + let 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); +} + +function updateIconResourceForAdaptive (preparedIcons, resourceMap, platformResourcesDir) { + let android_icons = preparedIcons.android_icons; + let default_icon = preparedIcons.default_icon; + + // The source paths for icons and splashes are relative to + // project's config.xml location, so we use it as base path. + let background; + let foreground; + let targetPathBackground; + let targetPathForeground; + + for (let density in android_icons) { + let backgroundVal = '@mipmap/ic_launcher_background'; + let foregroundVal = '@mipmap/ic_launcher_foreground'; + + background = android_icons[density].background; + foreground = android_icons[density].foreground; + + if (background.startsWith('@color')) { + // Colors Use Case + backgroundVal = background; // Example: @color/background_foobar_1 + } else if (path.extname(path.basename(background)) === '.xml') { + // Vector Use Case + targetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_background.xml', path.basename(android_icons[density].background)); + resourceMap[targetPathBackground] = android_icons[density].background; + } else if (path.extname(path.basename(background)) === '.png') { + // Images Use Case + targetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_background.png', path.basename(android_icons[density].background)); + resourceMap[targetPathBackground] = android_icons[density].background; + } + + if (foreground.startsWith('@color')) { + // Colors Use Case + foregroundVal = foreground; + } else if (path.extname(path.basename(foreground)) === '.xml') { + // Vector Use Case + targetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_foreground.xml', path.basename(android_icons[density].foreground)); + resourceMap[targetPathForeground] = android_icons[density].foreground; + } else if (path.extname(path.basename(foreground)) === '.png') { + // Images Use Case + targetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_foreground.png', path.basename(android_icons[density].foreground)); + resourceMap[targetPathForeground] = android_icons[density].foreground; + } + + // create an XML for DPI and set color + const icLauncherTemplate = ` + + + +`; + + let launcherXmlPath = path.join(platformResourcesDir, 'mipmap-' + density + '-v26', 'ic_launcher.xml'); + + // Remove the XML from the resourceMap so the file does not get removed. + delete resourceMap[launcherXmlPath]; + + fs.writeFileSync(path.resolve(launcherXmlPath), icLauncherTemplate); + } + + // There's no "default" drawable, so assume default == mdpi. + if (default_icon && !android_icons.mdpi) { + let defaultTargetPathBackground; + let defaultTargetPathForeground; + + if (background.startsWith('@color')) { + // Colors Use Case + targetPathBackground = default_icon.background; + } else if (path.extname(path.basename(background)) === '.xml') { + // Vector Use Case + defaultTargetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_background.xml', path.basename(default_icon.background)); + resourceMap[defaultTargetPathBackground] = default_icon.background; + } else if (path.extname(path.basename(background)) === '.png') { + // Images Use Case + defaultTargetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_background.png', path.basename(default_icon.background)); + resourceMap[defaultTargetPathBackground] = default_icon.background; + } + + if (foreground.startsWith('@color')) { + // Colors Use Case + targetPathForeground = default_icon.foreground; + } else if (path.extname(path.basename(foreground)) === '.xml') { + // Vector Use Case + defaultTargetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_foreground.xml', path.basename(default_icon.foreground)); + resourceMap[defaultTargetPathForeground] = default_icon.foreground; + } else if (path.extname(path.basename(foreground)) === '.png') { + // Images Use Case + defaultTargetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_foreground.png', path.basename(default_icon.foreground)); + resourceMap[defaultTargetPathForeground] = default_icon.foreground; + } + } + + return resourceMap; +} + +function updateIconResourceForLegacy (preparedIcons, resourceMap, platformResourcesDir) { + let android_icons = preparedIcons.android_icons; + let default_icon = preparedIcons.default_icon; + + // The source paths for icons and splashes are relative to + // project's config.xml location, so we use it as base path. + for (var density in android_icons) { + var targetPath = getImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher.png', path.basename(android_icons[density].src)); + resourceMap[targetPath] = android_icons[density].src; + } + + // There's no "default" drawable, so assume default == mdpi. + if (default_icon && !android_icons.mdpi) { + var defaultTargetPath = getImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher.png', path.basename(default_icon.src)); + resourceMap[defaultTargetPath] = default_icon.src; + } + + return resourceMap; +} + +function prepareIcons (icons) { // http://developer.android.com/design/style/iconography.html - var sizeToDensityMap = { + const SIZE_TO_DENSITY_MAP = { 36: 'ldpi', 48: 'mdpi', 72: 'hdpi', @@ -335,11 +520,15 @@ function updateIcons (cordovaProject, platformResourcesDir) { 144: 'xxhdpi', 192: 'xxxhdpi' }; + + let android_icons = {}; + let default_icon; + // find the best matching icon for a given density or size // @output android_icons var parseIcon = function (icon, icon_size) { // do I have a platform icon for that density already - var density = icon.density || sizeToDensityMap[icon_size]; + var density = icon.density || SIZE_TO_DENSITY_MAP[icon_size]; if (!density) { // invalid icon defition ( or unsupported size) return; @@ -355,12 +544,34 @@ function updateIcons (cordovaProject, platformResourcesDir) { for (var i = 0; i < icons.length; i++) { var icon = icons[i]; var size = icon.width; + if (!size) { size = icon.height; } + if (!size && !icon.density) { if (default_icon) { - events.emit('verbose', 'Found extra default icon: ' + icon.src + ' (ignoring in favor of ' + default_icon.src + ')'); + let found = {}; + let favor = {}; + + // populating found icon. + if (icon.background && icon.foreground) { + found.background = icon.background; + found.foreground = icon.foreground; + } + if (icon.src) { + found.src = icon.src; + } + + if (default_icon.background && default_icon.foreground) { + favor.background = default_icon.background; + favor.foreground = default_icon.foreground; + } + if (default_icon.src) { + favor.src = default_icon.src; + } + + events.emit('verbose', 'Found extra default icon: ' + JSON.stringify(found) + ' and ignoring in favor of ' + JSON.stringify(favor) + '.'); } else { default_icon = icon; } @@ -369,36 +580,35 @@ function updateIcons (cordovaProject, platformResourcesDir) { } } - // The source paths for icons and splashes are relative to - // project's config.xml location, so we use it as base path. - for (var density in android_icons) { - var targetPath = getImageResourcePath( - platformResourcesDir, 'mipmap', density, 'icon.png', path.basename(android_icons[density].src)); - resourceMap[targetPath] = android_icons[density].src; - } - - // There's no "default" drawable, so assume default == mdpi. - if (default_icon && !android_icons.mdpi) { - var defaultTargetPath = getImageResourcePath( - platformResourcesDir, 'mipmap', 'mdpi', 'icon.png', path.basename(default_icon.src)); - resourceMap[defaultTargetPath] = default_icon.src; - } - - events.emit('verbose', 'Updating icons at ' + platformResourcesDir); - FileUpdater.updatePaths( - resourceMap, { rootDir: cordovaProject.root }, logFileOp); + return { + android_icons: android_icons, + default_icon: default_icon + }; } function cleanIcons (projectRoot, projectConfig, platformResourcesDir) { var icons = projectConfig.getIcons('android'); - if (icons.length > 0) { - var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'icon.png'); - events.emit('verbose', 'Cleaning icons at ' + platformResourcesDir); - // No source paths are specified in the map, so updatePaths() will delete the target files. - FileUpdater.updatePaths( - resourceMap, { rootDir: projectRoot, all: true }, logFileOp); + // 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; } + + let resourceMap = Object.assign( + {}, + mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.png'), + mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'), + mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'), + mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'), + mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'), + mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.xml') + ); + + events.emit('verbose', 'Cleaning icons at ' + platformResourcesDir); + + // No source paths are specified in the map, so updatePaths() will delete the target files. + FileUpdater.updatePaths(resourceMap, { rootDir: projectRoot, all: true }, logFileOp); } /** diff --git a/bin/templates/project/AndroidManifest.xml b/bin/templates/project/AndroidManifest.xml index e0c53aaab0..9c36963a9e 100644 --- a/bin/templates/project/AndroidManifest.xml +++ b/bin/templates/project/AndroidManifest.xml @@ -30,7 +30,7 @@ - + + + + \ No newline at end of file diff --git a/bin/templates/project/res/mipmap-hdpi-v26/ic_launcher_background.png b/bin/templates/project/res/mipmap-hdpi-v26/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..021da864fe05ea698b9b08674f4990eeb6dac7bf GIT binary patch literal 14629 zcmeI3O^@3|7{{k7g597(RfIsCT(?L?kc^%8SWc?#X4|YpwyWJNWKYzwC%e`rwy~Wi zyW&tS9Ow;kLWs|RkT`Haf)jVn{RSWq+z_W_#&(h?*<`0hJx-*=k7xe>=dpkD5?}my zd+Xkn)LSWp(3QNWNQgkFA)eJ`P}zj+g(@-4g74%^N5 zHPh{949o41%&6~CHA4FBk!P4kB$PVjz;>$gUqAjVOSV;&KP)trrngQG?Z$~uc2Bli z=E;#+vEh(RprAl^fZiz z!(nEa%eejlRx6bXR(zSm}IkFqYW9`wlt$$?sQ6OH(eq{HJz_i3h9oa8fnWiJC;TArJ_=fAU2!OelB(0 zH3w|HB&n@uObzVkQs4J&y4M*!pkY`4tR)ttIajJ-2XuxWgPBX`Z?v23l8?s@Cfx#!qnEt^!EYX&a1 z`^Fo?E`3lSwPK-=E9iK>dET*Yk4Udwx9JKF*t{&!N|9&2W1(?>nGtj(#(1c}UwSl> zaVvdbpwB9J@~|>H$dje;oP+5dJ?F$QohSlnaASdsiwFt?E=YqL3tU`8P#|zY8r)dm z;v#|qfeX^$#sU`?5flhqkOnsvxVVU*K;VKjxUs;+MFa%`7o@?B1uiZkC=j?H4Q?!O zaS=g*zy)b=V}Xl{2nqx)NP`;-TwFv@AaFq%+*sh^B7y>e3)0}m0v8t%6bM|91~(SC zxQL)Y;DR)`vB1Se1O);Yq`{2^E-oS{5V#->ZY*$d5kY~#1!-_&fs2a>3Ir}lgBuH6 zTtrYHa6uZ}Sm5F!f&zgH(%{Ay;z~_l|0524=Wj?~?tArvBlc>bWHxr12%Wr*(4$Wg z`uB_;e?w@XAoTkKgtV^^dc*zlqhIb)?QpZc)*3ze|U&mX_u ze)7r>jjJ~sUr1}GFRb2)57%z4u(NBdIXTet>xt;vXOWinULA|pPG?j6)TTAh&MqT! VnCc9zy+`yEZEkGUzrFL|^gkQX#C!k% literal 0 HcmV?d00001 diff --git a/bin/templates/project/res/mipmap-hdpi/icon.png b/bin/templates/project/res/mipmap-hdpi-v26/ic_launcher_foreground.png similarity index 100% rename from bin/templates/project/res/mipmap-hdpi/icon.png rename to bin/templates/project/res/mipmap-hdpi-v26/ic_launcher_foreground.png diff --git a/bin/templates/project/res/mipmap-hdpi/ic_launcher.png b/bin/templates/project/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..53842612476cfe0d35e54ca3db1238f50df14293 GIT binary patch literal 3345 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 literal 0 HcmV?d00001 diff --git a/bin/templates/project/res/mipmap-ldpi-v26/ic_launcher.xml b/bin/templates/project/res/mipmap-ldpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..be316184eb --- /dev/null +++ b/bin/templates/project/res/mipmap-ldpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/bin/templates/project/res/mipmap-ldpi-v26/ic_launcher_background.png b/bin/templates/project/res/mipmap-ldpi-v26/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..da47a979edb510836baaa5cea747732c1a0643c9 GIT binary patch literal 14566 zcmeI3PiW*+9LJw7ENi8wJt%?@vMa3U%u6QoH)Lk1GhJKQ)Y6XFp4>EfZL^(8vPq^h zEr_D0y@-g1MLl@)CV2KB2wr6oPu@H#f=BV7-S?6-^P7KtyRyd@n8|P6`+k4FrD>sy^$SvmTvDIdmh zpkq874vRyr=!XYbZ8REKDdAG7Koy1P#EY#_!Hce?NzU_hNMwg@5WBu7vAouvKZu*M z%nId4c3=GQm?Xfsfg1WaKWev7XeHOoeoW40^A6J0w=@hh5+AwbEI(d5%zOx7n#B9VT-D2!*Vw#NK$28BmBaKMcmHHEN4cw3bWNiZ8|DDY z=^S(gIaX{vRu-rQc^q5c_rtywx7@yUKyct471C0YX5e|vz?IB3 zecg*<%d^RPr$rlzuIuR9o~Bk+QZ6(!$1arXWvx)Rsy6*us@aO&s43NY0?{;~eI|9s zw+C#!WT~AeObzTasox4+y4P7fpkY`4q$TF0nJKmAMs$XrfSF6@Z?cenKi;D;f1TIK}8w*@q zL{K1bK^ojx;Nl{J0)Y$C;Kl+M7ZDT)T#yDg7Pz>Gpg`b)G`O+A#YF@K0vDvgjRh_) zA}A2JAPsITaB&eqfxrc6aASdsiwFt?E=YqL3tU`8P#|zY8r)dm;v#|qfeX^$#sU`? z5flhqkOnsvxVVU*K;VKjxbcO!md3CD5s$v}H>5B3eRlWdFX)SblD)QNB6Ru+LLYpD z&_8GN{5wJe1))FgAf(fm4PWp-efP&(R9j!~taL}e{`u3l%LrY$^wodw->bdXzIyri p=i}o2PiBsXUq5^np|i6~=$F5L`1oH_zfE(X_0^5eH*ehe@DXQwx$*!2 literal 0 HcmV?d00001 diff --git a/bin/templates/project/res/mipmap-ldpi-v26/ic_launcher_foreground.png b/bin/templates/project/res/mipmap-ldpi-v26/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..203223aff0e2e36b20fa06ee27a1e82db7908b8f GIT binary patch literal 1754 zcmV<01||84P)@+gST$gcT95#CyC5a@+9YK?D&* zYkksM`=T}GNz|QGv$L~ztc62We&|~TD8$RBoO9<9ne<-p-Xr30&f~q`oBI!hd5;Jv zr9P>YdI@;@AP(u_g4BNu@Zz6PN>6I7(ORRlM(Kbs2nhCu)&U=wu67^AB=E#R#Ef)k z2p-W|KPVxDLHR>s)FO{bI4?e+)){UGoNs9$~*(afc6*yrsYI6L96dTsxm-fTllJ~B0fJ9h{7K^*$gz8HXKe*HVAYRbMl5`WCb-cUY;?t*3^U4d)(QdcM^Bhp~O7S_R^!kYtC+^@LddsrG zpd=#aZx{30#Wz^pY*DXOF~*V`Lt!jaV`EI$$C;_unXFb3AP7U8cjVhH(!q*Yw@gqYsni8Cjm=oqx<2vjP0@K!U7uZ(3uT zUSuxFHKkI>k?|U9n{AX=fQsg!zi828YUg<*IxER`;WVMq`L#Bod|j_7o|Y;Cq!S>Hr|;(j`X>;hMF-#5F&oji^p1rF_t)r+1W{OS%xPhDwXJEIh*Y^6C$)bJ1jL>N=2Sguh%HD0o}ZyCJDdz@l(jwCJxx%?vVCU#wY5~@AK>rzRP&lr(Pdpyb?23 ztB|HC)>)KSMk)2a8WKlF3d*t!rPP*pZrNFPPud@FbY_ww%lOyII>*PyNaq(&QJJt@ z#u|gQ4jlv_9=EkkzgA@}D>%`Zpf*-vWu>*7vlPpSY>leSh%@9+N^MzZo7TB|dcBlJ zqt3~rGhDm1MmY#5ADspfK%iW{t>-J$!~{x&%vjExK8-01gF%KMAkqZ>J3+=+lp=S| zukVMi>(>|g#-m^5YyAvs?OrO}3u5g57DV;~n-GS(IqBxoDqdv&n{^S%NBx%#6%>X6 zT5Fuk-zkdxEI?5hs+E|=+;Q5iws`MRN-6Ih&I__9V((^3pcU0>thPG|X74b2??L39 zQSQK~#Hck|2Z+eqMPbOYoH&k{pTEJ=KYRA&w4a@GPO`1-gq@^Mx0{l5`*eFLNs?l% z%hLYf+%v!V!^`tGmWbmLrZBsSK;*7bcBn(!TU+c|x+dP|)|kke5Nj=iJbP_oV&Y1g zrrugh5CnMfh~LlCo-k1UR&(>pR?_`g7z7VE>ktu?Qn?6gf()Y_?T|GVYYfiWHEV6h zTFW5IK*8y`xwnoSsYktDPdR6?*5ItgIfrw*O*GJ2ZML_gFbJ;J$H#EaqqG7=2Uuh8 zE*#h)Yj@kIQmSd4d(k>~2BUgf2SpS`f7{;f80*}hy!Yck;=L&Fh!+v@^(@c3W3}q$ wvBp$KYxR3U%D@;fkD@u!o + + + + \ No newline at end of file diff --git a/bin/templates/project/res/mipmap-mdpi-v26/ic_launcher_background.png b/bin/templates/project/res/mipmap-mdpi-v26/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..74e56e5b0afe0bbcf93b3423e585e114ed2bd965 GIT binary patch literal 14582 zcmeI3O>E;t6vt;-fp&`u2P8n8j8{mDSZC~fw6W!6Rgx~LgiF;1wLP(pJ#DQfwy~W} zT7k5DNQfhQLWna$S_yFni4$k;TsiS25ZX&mWyW@smo(|@uJ$;V(!9?6|L=`|^ATVC z`NsNNiwmzTAcPjzTFp)Rt+LORXXxMUr%pbjUsuD{Zj8{gFR;%g^wrldBUHWawRe&o z>utjcdIj4JI;1e{g;b4@d2<-r&LK&p4%zqon*7fXKgp8k*5vJqrCMQw9C)qch-@9N zx1HldM|b6$^#yZi&;&h_*wV1q^4TeA8Wdh(G}pnTOM1jlV(Qao`oe=C3F3obPRUXC z+`@EDENfJI=6HL(nWf`o^$talBc17t+eab6n+Tb8Z#+2@nOM)< zv6G=U$HsaxTe=jo88Yd;8jXn9Nf5Pzpj*#Y*~S?{snKAoYFWB&*^cKkuCJST+BBZ= zaX!+t6H=$%s-jkuVyUfFjq;LFuDrq4r3#W{%BdVy;Cg#UlR3(5tzwi)hBlD{D5rDK z9pu`H{ZLt;7UXdqV=st$c2f6x_CCR(zi;AkBT$akmC*>gK}3f|>LnA;Y6h-!tr=^6 zoY=lY)|z$NQ1Cq0pqsE-A{|#LmDFXW+|hK!wsl=uTCSGM9j90%S_aXwp#5CxX5jSM ze#uk2kC+JpwD2uHW=D+am8zww`r#z4TNH z?Iq0r4-| zP+6)}H9tul>?H#`A}jlJO+4Ig&+<+hrwf>v{Q`8o$*IU%Cub<#_;k&lpHY(?YzAEo zbYylq3z~_~wT&xh`W-f_-F~WHE~@mx8vC1DVfVCk_hKvTp0!iixzQ3TT9#sU`?5flhqkOnsvxVVU*K;VKjxUs;+ zMFa%`7o@?B1uiZkC=j?H4Q?!OaS=g*zy)b=V}Xl{2nqx)NP`;-TwFv@AaFq%+*sh^ zB7y>e3)0}m0v8t%6bM|91~(SCxQL)Y;DR)`vB1Se1O);Yq`{2^E-oS{5V#->ZY*$d z5kY~#1!-_&fs2a>3Ir}lgBuH6TtrYHa6uZ}Sm5F!f&zgH(%{Ad7Z(u}2wac`Hx{_K zh@e2=f;70Xz{N!b1p*hO!HqA(wJ?7DkNEVRzX5%@@BSCoF?}&ma$1`fLdUNmboUd4 zPEP6f?+Eqj8;5_~M#%UQp_hVt@BMs>YFlf~mGI^Sd{1fBZk$1+g;# literal 0 HcmV?d00001 diff --git a/bin/templates/project/res/mipmap-mdpi-v26/ic_launcher_foreground.png b/bin/templates/project/res/mipmap-mdpi-v26/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..8ca658e720eff617817afee903d6de5cb831b2f3 GIT binary patch literal 2514 zcmV;@2`%=CP)Nf0hzA6bP$UpYzT#PRHUc4oGBH#0jkJ>AvaRdw$@hllF!nca9k zZ1a{m((SrkRo(ae&pG#;bN_HAXL2TIawb2?Vvc+0MUVcW0c-8E;{8Vzwoo;y%HhFu z4iDb1MS~!?;JyD|Rh5^)9I4Es7cag$0EZU)F%i|DFN@-esv=XxL{L@ys0dOc zxm-gzY8)-c0x;%n1|X`R1@nn8j4(k!5CjBaaA+P9g<(Ap0>a7MOx_D8BM1X(eEJFC zv&U+Bl#a(eJR*cXAgZsa>VileA~3P0D57!@G9t5Zs^1kZ@0{ za`kmOb8~p_+1lFXSAY2z_}OQk=I)&>g1}7I`!ty653lk6<$?DBmmj|QwU_^i*WX;F z)5sVW1vj_0`P1M3G{6HEzxSgp{^ZNgleOCj(7SVw?_PVIm%s5<8jX~yvKRxZdKvT| zfP1G=>YV_17I^gVjaR>Om94!VPd@$_);XG^gmxpvn1I#QoAi47hzJV{^Mql@hn~0u zB7{LeIoIMp*Sq}f3*Y3of9u!jcDsaO0Pv`)KC8+foJOhBhR|;SUw`=dm;UN2+`E6D zRuWNJhqVq7VOSIl#|73othH3m5t)EuIAS;&;YIMyabstnkAC0@{^je>v%9-PRarQw z6`wT5d;{R(#iK*$*fctk25%EOSFV1K?)H6_IvrHOm^$Z+2w9r4)R|*(uFXX42DCz3UL%N)iH@8&Nov2@~ba08jo3ATp*5P zk|ZHblc%C6dXA%;0pNr^kPil*SNO~fkO=b&3;giSn^^BzdE`9STAEo}=Xq6}a|EWg zi**+9f^&{2j@Z0?hc|BCB93EJK~#AB+!Cul+Tx{`{+{3colmm0wM`g?)7tSF=WGuA z@w);rE{Zkh+)!0p#(?vJF_2{`%|?U37_u~lMp`?)EReX33Bzf{Mx-uSt#-!sAH2!- z?K>v1^ zT)TyHmR`RkiK5zC*0Q6}lALH_LGK0UJgs(<8*km>```Z|`s9<0`}+jFJv2!fjK<8j zGTwh_g`%hk!;ooP1^S9H!MBgo@z^~eB0Vr0(lvTxGXNP{2@bs^J z3YTW|@9!`ej>+>O`7o!bEZ6`0f4Lh){L$q<=flr@jBc+F;<47!Zlo+O&Qla6GRaWR zS)6qn*4o~?24IX)W6U}{(1nsU8yKKJ$Qh5u?CcMyvNpf6GLL3W?(g-;^PK%b&bTPK z-M!1kMwjILBmCl{Z7yAUoSh`ah)`NfJ8RHxXB0(ID{mdnd7O9a&e>zP@v$LPH($D{ zC^~7{y!T|;GNFOJ{XU^8z0sJ4!dzsi2j616@_! z_9EvEigz9mTFs2TUY}N+Pz`gs-A(@EzGruHgJLv-I3_fPUVlJQRJ7(=$j&x@_r@LG zxOtNcWr4I(#0wYBFH;sJ&Uu2sOjGigk!bDty2`<$DfqY}uXfOE@>42L5` zJfdcLQtJZU{f(;L5bse8 z-V38~!P3$K}P*RaF=R-piWv2S>v}Kj+-?A}i;XS>M{Bl_vG3Gl$8MTH~Y0l4;ZS z{zuL+Ki_6=Z-Dm#)GPNFPwhVA=1Y;JaGHnUX`nKwajVXCyw7>dKJTnKj6=6z>nQ z8R)9PtWH_4vLzr)wQ`K_(n-8&y&d2Ho{vMeWT zoXqHz*>~~v)q57^+b^u%y!G+FdHJ8Wc6NI-(gf$+tbnQLny8Lzn&x-}CvIW@V**rl z(>pgwbDpv&NgF9?5?@b}_+A)AbtRpg$_`VGhj~&1?C$Mz<-e}qTkf>4HyX)>vaDtt z>f|)Gc|hg82M@t^UK7!mM5F`?FVawO?N;+j z7=~1py(X&vXjJdaHZ9CThZ!SnE{==xnsuJ}cI%2Ud<7)}3Tgr&1ztNXfHOIhGdYtp c`N@|514Xr)`8~{Q{{R3007*qoM6N<$g2z$aLjV8( literal 0 HcmV?d00001 diff --git a/bin/templates/project/res/mipmap-mdpi/icon.png b/bin/templates/project/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from bin/templates/project/res/mipmap-mdpi/icon.png rename to bin/templates/project/res/mipmap-mdpi/ic_launcher.png diff --git a/bin/templates/project/res/mipmap-xhdpi-v26/ic_launcher.xml b/bin/templates/project/res/mipmap-xhdpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..be316184eb --- /dev/null +++ b/bin/templates/project/res/mipmap-xhdpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/bin/templates/project/res/mipmap-xhdpi-v26/ic_launcher_background.png b/bin/templates/project/res/mipmap-xhdpi-v26/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..d0cb62dde334770546850d4206949330779a44d9 GIT binary patch literal 688 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 literal 0 HcmV?d00001 diff --git a/bin/templates/project/res/mipmap-xhdpi/icon.png b/bin/templates/project/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from bin/templates/project/res/mipmap-xhdpi/icon.png rename to bin/templates/project/res/mipmap-xhdpi/ic_launcher.png diff --git a/bin/templates/project/res/mipmap-xxhdpi-v26/ic_launcher.xml b/bin/templates/project/res/mipmap-xxhdpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..be316184eb --- /dev/null +++ b/bin/templates/project/res/mipmap-xxhdpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/bin/templates/project/res/mipmap-xxhdpi-v26/ic_launcher_background.png b/bin/templates/project/res/mipmap-xxhdpi-v26/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..ec38d403292098a43a88ec4ae3f1da2a78cb61ad GIT binary patch literal 1051 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 P%sBw0rmKopwvPHg%fcQz literal 0 HcmV?d00001 diff --git a/bin/templates/project/res/mipmap-xxhdpi/icon.png b/bin/templates/project/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from bin/templates/project/res/mipmap-xxhdpi/icon.png rename to bin/templates/project/res/mipmap-xxhdpi/ic_launcher.png diff --git a/bin/templates/project/res/mipmap-xxxhdpi-v26/ic_launcher.xml b/bin/templates/project/res/mipmap-xxxhdpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..be316184eb --- /dev/null +++ b/bin/templates/project/res/mipmap-xxxhdpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/bin/templates/project/res/mipmap-xxxhdpi-v26/ic_launcher_background.png b/bin/templates/project/res/mipmap-xxxhdpi-v26/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..d652c08407faaddae6a079b8a11128ac58a25a80 GIT binary patch literal 1390 zcmeAS@N?(olHy`uVBq!ia0y~yVB7%094tVQB=;W+ffP%+qpu?a!^VE@KZ&eBzCyA` zkS_y6l^O#>Lkk1LFQ8Dv3kHT#0|tgy2@DKYGZ+}e3+C(!v;j&mC3(BMFfgp@RW<_h zI14-?iy0WWg+Q3`(%rg0Ktc8rPhVH|M{KOZ98BVckGBCWJnZS>7*cWT?PW(!1_g!# z4qF%3_T+Ubo``L#HTy2`@9U6!+$ UnmDS~082OqPgg&ebxsLQ0P%u%@|DV zde+`Iulu@pgpz_3DiR?Q002Ohkrw{}003+L8whZam46B>bdU+gTtr?30H}>ael>)J z{Qhh#{X-rA@S*_#0)hd6XUI~(ApqdY0stHv006ux005ptMyoPE03j~#8ds>^M4ZfUy=YnEbkeRD&kx0 zOy~IK$M?#+6MUE8Ve!6erohxYDS$<1{j1%_H{okEpw8P3plkCyrQoF&Z?`w_zJqj^ z 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 E53tcm6951J literal 0 HcmV?d00001 diff --git a/bin/templates/project/res/mipmap-xxxhdpi/icon.png b/bin/templates/project/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from bin/templates/project/res/mipmap-xxxhdpi/icon.png rename to bin/templates/project/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/spec/unit/prepare.spec.js b/spec/unit/prepare.spec.js new file mode 100644 index 0000000000..3b133c1521 --- /dev/null +++ b/spec/unit/prepare.spec.js @@ -0,0 +1,757 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + 'License'); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +var rewire = require('rewire'); +var path = require('path'); +var CordovaError = require('cordova-common').CordovaError; + +const PATH_RESOURCE = path.join('platforms', 'android', 'app', 'src', 'main', 'res'); + +/** + * Creates blank resource map object, used for testing. + * + * @param {String} target specific resource item + */ +function createResourceMap (target) { + let resources = {}; + + [ + 'mipmap-ldpi', + 'mipmap-mdpi', + 'mipmap-hdpi', + 'mipmap-xhdpi', + 'mipmap-xxhdpi', + 'mipmap-xxxhdpi', + 'mipmap-ldpi-v26', + 'mipmap-mdpi-v26', + 'mipmap-hdpi-v26', + 'mipmap-xhdpi-v26', + 'mipmap-xxhdpi-v26', + 'mipmap-xxxhdpi-v26' + ].forEach((mipmap) => { + if (!target || target === 'ic_launcher.png') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher.png')] = null; + if (!target || target === 'ic_launcher_foreground.png') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_foreground.png')] = null; + if (!target || target === 'ic_launcher_background.png') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_background.png')] = null; + if (!target || target === 'ic_launcher_foreground.xml') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_foreground.xml')] = null; + if (!target || target === 'ic_launcher_background.xml') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_background.xml')] = null; + + if ( + !mipmap.includes('-v26') && + (!target || target === 'ic_launcher.xml') + ) { + resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher.xml')] = null; + } + }); + + return resources; +} + +/** + * Create a mock item from the getIcon collection with the supplied updated data. + * + * @param {Object} data Changes to apply to the mock getIcon item + */ +function mockGetIconItem (data) { + return Object.assign({}, { + src: undefined, + target: undefined, + density: undefined, + platform: 'android', + width: undefined, + height: undefined, + background: undefined, + foreground: undefined + }, data); +} + +describe('updateIcons method', function () { + // Rewire + let prepare; + + // Spies + let updateIconResourceForAdaptiveSpy; + let updateIconResourceForLegacySpy; + let emitSpy; + let updatePathsSpy; + + // Mock Data + let cordovaProject; + let platformResourcesDir; + + beforeEach(function () { + prepare = rewire('../../bin/templates/cordova/lib/prepare'); + + cordovaProject = { + root: '/mock', + projectConfig: { + path: '/mock/config.xml', + cdvNamespacePrefix: 'cdv' + }, + locations: { + plugins: '/mock/plugins', + www: '/mock/www' + } + }; + platformResourcesDir = PATH_RESOURCE; + + emitSpy = jasmine.createSpy('emit'); + prepare.__set__('events', { + emit: emitSpy + }); + + updatePathsSpy = jasmine.createSpy('updatePaths'); + prepare.__set__('FileUpdater', { + updatePaths: updatePathsSpy + }); + + // mocking initial responses for mapImageResources + prepare.__set__('mapImageResources', function (rootDir, subDir, type, resourceName) { + if (resourceName.includes('ic_launcher.png')) { + return createResourceMap('ic_launcher.png'); + } else if (resourceName.includes('ic_launcher_foreground.png')) { + return createResourceMap('ic_launcher_foreground.png'); + } else if (resourceName.includes('ic_launcher_background.png')) { + return createResourceMap('ic_launcher_background.png'); + } else if (resourceName.includes('ic_launcher_foreground.xml')) { + return createResourceMap('ic_launcher_foreground.xml'); + } else if (resourceName.includes('ic_launcher_background.xml')) { + return createResourceMap('ic_launcher_background.xml'); + } else if (resourceName.includes('ic_launcher.xml')) { + return createResourceMap('ic_launcher.xml'); + } + }); + }); + + it('Test#001 : Should detect no defined icons.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return []; + }; + + updateIcons(cordovaProject, platformResourcesDir); + + // The emit was called + expect(emitSpy).toHaveBeenCalled(); + + // The emit message was. + let actual = emitSpy.calls.argsFor(0)[1]; + let expected = 'This app does not have launcher icons defined'; + expect(actual).toEqual(expected); + }); + + it('Test#002 : Should detech incorrect configrations for adaptive icon and throws error.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({ + density: 'mdpi', + background: 'res/icon/android/mdpi-background.png' + })]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('One of the following attributes are set but missing the other for the density type: mdpi. Please ensure that all require attributes are defined.') + ); + }); + + it('Test#003 : Should detech incorrect configrations (missing foreground) for adaptive icon and throw an error.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({ + density: 'mdpi', + background: 'res/icon/android/mdpi-background.png' + })]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('One of the following attributes are set but missing the other for the density type: mdpi. Please ensure that all require attributes are defined.') + ); + }); + + it('Test#004 : Should detech incorrect configrations (missing background) for adaptive icon and throw an error.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({ + density: 'mdpi', + foreground: 'res/icon/android/mdpi-foreground.png' + })]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('One of the following attributes are set but missing the other for the density type: mdpi. Please ensure that all require attributes are defined.') + ); + }); + + it('Test#005 : Should detech incorrect configrations and throw an error.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({density: 'mdpi'})]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('One of the following attributes are set but missing the other for the density type: mdpi. Please ensure that all require attributes are defined.') + ); + }); + + it('Test#006 : Should display incorrect configuration with density in message.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({density: 'mdpi'})]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('One of the following attributes are set but missing the other for the density type: mdpi. Please ensure that all require attributes are defined.') + ); + }); + + it('Test#007 : Should display incorrect configuration with size in message from height.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({height: '192'})]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('One of the following attributes are set but missing the other for the density type: size=192. Please ensure that all require attributes are defined.') + ); + }); + + it('Test#008 : Should display incorrect configuration with size in message from width.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({width: '192'})]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('One of the following attributes are set but missing the other for the density type: size=192. Please ensure that all require attributes are defined.') + ); + }); + + it('Test#009 : Should detech incorrect configrations (missing background) for adaptive icon and throw an error.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({ + density: 'mdpi', + foreground: 'res/icon/android/mdpi-foreground.png' + })]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('One of the following attributes are set but missing the other for the density type: mdpi. Please ensure that all require attributes are defined.') + ); + }); + + it('Test#010 : Should detech adaptive icon with vector foreground and throws error for missing backwards compatability settings.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({ + density: 'mdpi', + background: 'res/icon/android/mdpi-background.png', + foreground: 'res/icon/android/mdpi-foreground.xml' + })]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('For the following icons with the density of: mdpi, 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.') + ); + }); + + it('Test#011 : Should detech adaptive icon with color foreground and throws error for missing backwards compatability settings.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({ + density: 'mdpi', + background: 'res/icon/android/mdpi-background.png', + foreground: '@color/background' + })]; + }; + + expect(function () { + updateIcons(cordovaProject, platformResourcesDir); + }).toThrow( + new CordovaError('For the following icons with the density of: mdpi, 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.') + ); + }); + + it('Test#012 : Should update paths with adaptive and standard icons. Standard icon comes from adaptive foreground', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({ + density: 'mdpi', + background: 'res/icon/android/mdpi-background.png', + foreground: 'res/icon/android/mdpi-foreground.png' + })]; + }; + + // Creating Spies + let resourceMap = createResourceMap(); + let phaseOneModification = {}; + phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_foreground.png')] = 'res/icon/android/mdpi-foreground.png'; + phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png'; + let phaseOneUpdatedIconsForAdaptive = Object.assign({}, resourceMap, phaseOneModification); + + updateIconResourceForAdaptiveSpy = jasmine.createSpy('updateIconResourceForAdaptiveSpy'); + prepare.__set__('updateIconResourceForAdaptive', function (preparedIcons, resourceMap, platformResourcesDir) { + updateIconResourceForAdaptiveSpy(); + return phaseOneUpdatedIconsForAdaptive; + }); + + let phaseTwoModification = {}; + phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi', 'ic_launcher.png')] = 'res/icon/android/mdpi-foreground.png'; + phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png'; + let phaseTwoUpdatedIconsForLegacy = Object.assign({}, phaseOneUpdatedIconsForAdaptive, phaseTwoModification); + + updateIconResourceForLegacySpy = jasmine.createSpy('updateIconResourceForLegacySpy'); + prepare.__set__('updateIconResourceForLegacy', function (preparedIcons, resourceMap, platformResourcesDir) { + updateIconResourceForLegacySpy(); + return phaseTwoUpdatedIconsForLegacy; + }); + + updateIcons(cordovaProject, platformResourcesDir); + + // The emit was called + expect(emitSpy).toHaveBeenCalled(); + + // The emit message was. + let actual = emitSpy.calls.argsFor(0)[1]; + let expected = 'Updating icons at ' + PATH_RESOURCE; + expect(actual).toEqual(expected); + + // Expected to be called. + expect(updatePathsSpy).toHaveBeenCalled(); + expect(updateIconResourceForAdaptiveSpy).toHaveBeenCalled(); + expect(updateIconResourceForLegacySpy).toHaveBeenCalled(); + + let actualResourceMap = updatePathsSpy.calls.argsFor(0)[0]; + let expectedResourceMap = phaseTwoUpdatedIconsForLegacy; + expect(actualResourceMap).toEqual(expectedResourceMap); + }); + + it('Test#013 : Should update paths with adaptive and standard icons.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({ + density: 'mdpi', + src: 'res/icon/android/mdpi-icon.png', + background: 'res/icon/android/mdpi-background.png', + foreground: 'res/icon/android/mdpi-foreground.png' + })]; + }; + + // Creating Spies + let resourceMap = createResourceMap(); + let phaseOneModification = {}; + phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_foreground.png')] = 'res/icon/android/mdpi-foreground.png'; + phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png'; + let phaseOneUpdatedIconsForAdaptive = Object.assign({}, resourceMap, phaseOneModification); + + updateIconResourceForAdaptiveSpy = jasmine.createSpy('updateIconResourceForAdaptiveSpy'); + prepare.__set__('updateIconResourceForAdaptive', function (preparedIcons, resourceMap, platformResourcesDir) { + updateIconResourceForAdaptiveSpy(); + return phaseOneUpdatedIconsForAdaptive; + }); + + let phaseTwoModification = {}; + phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi', 'ic_launcher.png')] = 'res/icon/android/mdpi-foreground.png'; + phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png'; + let phaseTwoUpdatedIconsForLegacy = Object.assign({}, phaseOneUpdatedIconsForAdaptive, phaseTwoModification); + + updateIconResourceForLegacySpy = jasmine.createSpy('updateIconResourceForLegacySpy'); + prepare.__set__('updateIconResourceForLegacy', function (preparedIcons, resourceMap, platformResourcesDir) { + updateIconResourceForLegacySpy(); + return phaseTwoUpdatedIconsForLegacy; + }); + + updateIcons(cordovaProject, platformResourcesDir); + + // The emit was called + expect(emitSpy).toHaveBeenCalled(); + + // The emit message was. + let actual = emitSpy.calls.argsFor(0)[1]; + let expected = 'Updating icons at ' + PATH_RESOURCE; + expect(actual).toEqual(expected); + + // Expected to be called. + expect(updatePathsSpy).toHaveBeenCalled(); + expect(updateIconResourceForAdaptiveSpy).toHaveBeenCalled(); + expect(updateIconResourceForLegacySpy).toHaveBeenCalled(); + + let actualResourceMap = updatePathsSpy.calls.argsFor(0)[0]; + let expectedResourceMap = phaseTwoUpdatedIconsForLegacy; + expect(actualResourceMap).toEqual(expectedResourceMap); + }); + + it('Test#014 : Should update paths with standard icons.', function () { + const updateIcons = prepare.__get__('updateIcons'); + + // mock data. + cordovaProject.projectConfig.getIcons = function () { + return [mockGetIconItem({ + density: 'mdpi', + src: 'res/icon/android/mdpi-icon.png' + })]; + }; + + // Creating Spies + let phaseOneUpdatedIconsForAdaptive = createResourceMap(); + + updateIconResourceForAdaptiveSpy = jasmine.createSpy('updateIconResourceForAdaptiveSpy'); + prepare.__set__('updateIconResourceForAdaptive', function (preparedIcons, resourceMap, platformResourcesDir) { + updateIconResourceForAdaptiveSpy(); + return phaseOneUpdatedIconsForAdaptive; + }); + + let phaseTwoModification = {}; + phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi', 'ic_launcher.png')] = 'res/icon/android/mdpi-icon.png'; + let phaseTwoUpdatedIconsForLegacy = Object.assign({}, phaseOneUpdatedIconsForAdaptive, phaseTwoModification); + + updateIconResourceForLegacySpy = jasmine.createSpy('updateIconResourceForLegacySpy'); + prepare.__set__('updateIconResourceForLegacy', function (preparedIcons, resourceMap, platformResourcesDir) { + updateIconResourceForLegacySpy(); + return phaseTwoUpdatedIconsForLegacy; + }); + + updateIcons(cordovaProject, platformResourcesDir); + + // The emit was called + expect(emitSpy).toHaveBeenCalled(); + + // The emit message was. + let actual = emitSpy.calls.argsFor(0)[1]; + let expected = 'Updating icons at ' + PATH_RESOURCE; + expect(actual).toEqual(expected); + + // Expected to be called. + expect(updatePathsSpy).toHaveBeenCalled(); + expect(updateIconResourceForAdaptiveSpy).not.toHaveBeenCalled(); + expect(updateIconResourceForLegacySpy).toHaveBeenCalled(); + + let actualResourceMap = updatePathsSpy.calls.argsFor(0)[0]; + let expectedResourceMap = phaseTwoUpdatedIconsForLegacy; + expect(actualResourceMap).toEqual(expectedResourceMap); + }); +}); + +describe('prepareIcons method', function () { + let prepare; + let emitSpy; + let prepareIcons; + + beforeEach(function () { + prepare = rewire('../../bin/templates/cordova/lib/prepare'); + + prepareIcons = prepare.__get__('prepareIcons'); + + // Creating Spies + emitSpy = jasmine.createSpy('emit'); + prepare.__set__('events', { + emit: emitSpy + }); + }); + + it('Test#001 : should emit extra default icon found for adaptive use case.', function () { + // mock data. + let ldpi = mockGetIconItem({ + density: 'ldpi', + background: 'res/icon/android/ldpi-background.png', + foreground: 'res/icon/android/ldpi-foreground.png' + }); + + let mdpi = mockGetIconItem({ + density: 'mdpi', + background: 'res/icon/android/mdpi-background.png', + foreground: 'res/icon/android/mdpi-foreground.png' + }); + + let icons = [ldpi, mdpi]; + let actual = prepareIcons(icons); + let expected = { + android_icons: {ldpi, mdpi}, + default_icon: undefined + }; + + expect(expected).toEqual(actual); + + }); + + it('Test#002 : should emit extra default icon found for legacy use case.', function () { + // mock data. + let ldpi = mockGetIconItem({ + src: 'res/icon/android/ldpi-icon.png', + density: 'ldpi' + }); + + let mdpi = mockGetIconItem({ + src: 'res/icon/android/mdpi-icon.png', + density: 'mdpi' + }); + + let icons = [ldpi, mdpi]; + let actual = prepareIcons(icons); + let expected = { + android_icons: {ldpi, mdpi}, + default_icon: undefined + }; + + expect(expected).toEqual(actual); + + }); +}); + +describe('updateIconResourceForLegacy method', function () { + let prepare; + + // Spies + let fsWriteFileSyncSpy; + + // Mock Data + let platformResourcesDir; + let preparedIcons; + let resourceMap; + + beforeEach(function () { + prepare = rewire('../../bin/templates/cordova/lib/prepare'); + + // Mocked Data + platformResourcesDir = PATH_RESOURCE; + preparedIcons = { + android_icons: { + mdpi: mockGetIconItem({ + src: 'res/icon/android/mdpi-icon.png', + density: 'mdpi' + }) + }, + default_icon: undefined + }; + + resourceMap = createResourceMap(); + + fsWriteFileSyncSpy = jasmine.createSpy('writeFileSync'); + prepare.__set__('fs', { + writeFileSync: fsWriteFileSyncSpy + }); + }); + + it('Test#001 : Should update resource map with prepared icons.', function () { + // Get method for testing + const updateIconResourceForLegacy = prepare.__get__('updateIconResourceForLegacy'); + + // Run Test + let expectedModification = {}; + expectedModification[path.join(PATH_RESOURCE, 'mipmap-mdpi', 'ic_launcher.png')] = 'res/icon/android/mdpi-icon.png'; + let expected = Object.assign({}, resourceMap, expectedModification); + let actual = updateIconResourceForLegacy(preparedIcons, resourceMap, platformResourcesDir); + + expect(actual).toEqual(expected); + + }); +}); + +describe('updateIconResourceForAdaptive method', function () { + let prepare; + + // Spies + let fsWriteFileSyncSpy; + + // Mock Data + let platformResourcesDir; + let preparedIcons; + let resourceMap; + + beforeEach(function () { + prepare = rewire('../../bin/templates/cordova/lib/prepare'); + + // Mocked Data + platformResourcesDir = PATH_RESOURCE; + preparedIcons = { + android_icons: { + mdpi: mockGetIconItem({ + density: 'mdpi', + background: 'res/icon/android/mdpi-background.png', + foreground: 'res/icon/android/mdpi-foreground.png' + }) + }, + default_icon: undefined + }; + + resourceMap = createResourceMap(); + + fsWriteFileSyncSpy = jasmine.createSpy('writeFileSync'); + prepare.__set__('fs', { + writeFileSync: fsWriteFileSyncSpy + }); + }); + + it('Test#001 : Should update resource map with prepared icons.', function () { + // Get method for testing + const updateIconResourceForAdaptive = prepare.__get__('updateIconResourceForAdaptive'); + + // Run Test + let expectedModification = {}; + expectedModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png'; + expectedModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_foreground.png')] = 'res/icon/android/mdpi-foreground.png'; + + let expected = Object.assign({}, resourceMap, expectedModification); + let actual = updateIconResourceForAdaptive(preparedIcons, resourceMap, platformResourcesDir); + + expect(actual).toEqual(expected); + + }); +}); + +describe('cleanIcons method', function () { + let prepare; + let emitSpy; + let updatePathsSpy; + + beforeEach(function () { + prepare = rewire('../../bin/templates/cordova/lib/prepare'); + + emitSpy = jasmine.createSpy('emit'); + prepare.__set__('events', { + emit: emitSpy + }); + + updatePathsSpy = jasmine.createSpy('updatePaths'); + prepare.__set__('FileUpdater', { + updatePaths: updatePathsSpy + }); + }); + + it('Test#001 : should detect that the app does not have defined icons.', function () { + // Mock + let icons = []; + let projectRoot = '/mock'; + let projectConfig = { + getIcons: function () { return icons; }, + path: '/mock/config.xml', + cdvNamespacePrefix: 'cdv' + }; + let platformResourcesDir = PATH_RESOURCE; + + const cleanIcons = prepare.__get__('cleanIcons'); + cleanIcons(projectRoot, projectConfig, platformResourcesDir); + + let actualEmitMessage = emitSpy.calls.argsFor(0)[1]; + expect(actualEmitMessage).toContain('This app does not have launcher icons defined'); + }); + + it('Test#002 : Should clean paths for adaptive icons.', function () { + // Mock + let icons = [mockGetIconItem({ + density: 'mdpi', + background: 'res/icon/android/mdpi-background.png', + foreground: 'res/icon/android/mdpi-foreground.png' + })]; + let projectRoot = '/mock'; + let projectConfig = { + getIcons: function () { return icons; }, + path: '/mock/config.xml', + cdvNamespacePrefix: 'cdv' + }; + let platformResourcesDir = PATH_RESOURCE; + + var expectedResourceMapBackground = createResourceMap('ic_launcher_background.png'); + + // mocking initial responses for mapImageResources + prepare.__set__('mapImageResources', function (rootDir, subDir, type, resourceName) { + if (resourceName.includes('ic_launcher_background.png')) { + return expectedResourceMapBackground; + } + }); + + const cleanIcons = prepare.__get__('cleanIcons'); + cleanIcons(projectRoot, projectConfig, platformResourcesDir); + + let actualResourceMapBackground = updatePathsSpy.calls.argsFor(0)[0]; + expect(actualResourceMapBackground).toEqual(expectedResourceMapBackground); + }); + + it('Test#003 : Should clean paths for legacy icons.', function () { + // Mock + let icons = [mockGetIconItem({ + src: 'res/icon/android/mdpi.png', + density: 'mdpi' + })]; + + let projectRoot = '/mock'; + let projectConfig = { + getIcons: function () { return icons; }, + path: '/mock/config.xml', + cdvNamespacePrefix: 'cdv' + }; + let platformResourcesDir = PATH_RESOURCE; + + var expectedResourceMap = createResourceMap(); + + // mocking initial responses for mapImageResources + prepare.__set__('mapImageResources', function (rootDir, subDir, type, resourceName) { + return expectedResourceMap; + }); + + const cleanIcons = prepare.__get__('cleanIcons'); + cleanIcons(projectRoot, projectConfig, platformResourcesDir); + + let actualResourceMap = updatePathsSpy.calls.argsFor(0)[0]; + expect(actualResourceMap).toEqual(expectedResourceMap); + }); +});