diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a6c40e6..59842dbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ ## [Unreleased] +### Fixed +- Fix flashing firmware on Android [support#403]. + +### Changed +- Checksum is now validated as firmware flash progresses instead of just at the + end [support#433]. ## [1.1.0-beta.3] - 2021-07-20 @@ -46,13 +52,15 @@ Prerelease changes are documented at [support#48]. - + [issue#470]: https://github.com/pybricks/pybricks-code/issues/470 [issue#471]: https://github.com/pybricks/pybricks-code/issues/471 [issue#472]: https://github.com/pybricks/pybricks-code/issues/472 [support#48]: https://github.com/pybricks/support/issues/48 [support#375]: https://github.com/pybricks/support/issues/375 [support#378]: https://github.com/pybricks/support/issues/378 +[support#403]: https://github.com/pybricks/support/issues/403 +[support#433]: https://github.com/pybricks/support/issues/433 [v3.0.0]: https://github.com/pybricks/pybricks-micropython/blob/master/CHANGELOG.md#300---2021-06-08 [v3.1.0a1]: https://github.com/pybricks/pybricks-micropython/blob/master/CHANGELOG.md#310a1---2021-06-23 [v3.1.0a2]: https://github.com/pybricks/pybricks-micropython/blob/master/CHANGELOG.md#310a2---2021-07-06 diff --git a/package.json b/package.json index f1c9e4b0..7e09c02e 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@testing-library/user-event": "^13.2.0", "@types/file-saver": "^2.0.3", "@types/jest": "^26.0.24", - "@types/node": "^12.20.16", + "@types/node": "^12.20.19", "@types/react": "^16.14.11", "@types/react-dom": "^16.9.14", "@types/react-redux": "^7.1.18", @@ -92,7 +92,7 @@ "eslint-plugin-prettier": "^3.4.0", "eslint-plugin-react": "^7.23.2", "eslint-plugin-total-functions": "^4.9.0", - "jest-mock-extended": "^1.0.18", + "jest-mock-extended": "^2.0.1", "prettier": "^2.3.2" } } diff --git a/src/firmware/sagas.ts b/src/firmware/sagas.ts index 792eb1be..dda1f939 100644 --- a/src/firmware/sagas.ts +++ b/src/firmware/sagas.ts @@ -55,6 +55,7 @@ import { import { RootState } from '../reducers'; import { defined, hex, maybe } from '../utils'; import { fmod, sumComplement32 } from '../utils/math'; +import { isAndroid } from '../utils/os'; import { FailToFinishReasonType, FlashFirmwareActionType, @@ -376,8 +377,9 @@ function* flashFirmware(action: FlashFirmwareFlashAction): Generator { yield* disconnectAndCancel(); } - // 14 is "safe" size for all hubs - const maxDataSize = MaxProgramFlashSize.get(info.hubType) || 14; + // 14 is "safe" size for all hubs and Android + const maxDataSize = + (!isAndroid() && MaxProgramFlashSize.get(info.hubType)) || 14; let runningChecksum = 0xff; diff --git a/src/utils/os.test.ts b/src/utils/os.test.ts index 90c3d947..c21b28da 100644 --- a/src/utils/os.test.ts +++ b/src/utils/os.test.ts @@ -1,12 +1,23 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2021 The Pybricks Authors -import { isMacOS, isWindows, prefersDarkMode } from './os'; +import { isAndroid, isMacOS, isWindows, prefersDarkMode } from './os'; afterEach(() => { jest.resetAllMocks(); }); +describe('isAndroid', () => { + test('is true', () => { + jest.spyOn(navigator, 'userAgent', 'get').mockReturnValue('Android'); + expect(isAndroid()).toBeTruthy(); + }); + test('is false', () => { + jest.spyOn(navigator, 'userAgent', 'get').mockReturnValue('Linux'); + expect(isAndroid()).toBeFalsy(); + }); +}); + describe('isMacOS', () => { test('is true', () => { jest.spyOn(navigator, 'platform', 'get').mockReturnValue('MacIntel'); diff --git a/src/utils/os.ts b/src/utils/os.ts index 12685d2e..5fe83dfd 100644 --- a/src/utils/os.ts +++ b/src/utils/os.ts @@ -3,6 +3,17 @@ // Utility functions for dealing with operating systems. +// TODO: replace with navigator.userAgentData when it is more widely available +// https://developer.mozilla.org/en-US/docs/Web/API/User-Agent_Client_Hints_API + +/** + * Tests if we are running on Android. + * @returns `true` if running on Android, otherwise `false`. + */ +export function isAndroid(): boolean { + return /android/i.test(navigator.userAgent); +} + /** * Tests if we are running on macOS. * @returns `true` if running on macOS, otherwise `false`. diff --git a/yarn.lock b/yarn.lock index 72ff5bb9..2888fd33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2044,10 +2044,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.3.3.tgz#0c30adff37bbbc7a50eb9b58fae2a504d0d88038" integrity sha512-8h7k1YgQKxKXWckzFCMfsIwn0Y61UK6tlD6y2lOb3hTOIMlK3t9/QwHOhc81TwU+RMf0As5fj7NPjroERCnejQ== -"@types/node@^12.20.16": - version "12.20.16" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.16.tgz#1acf34f6456208f495dac0434dd540488d17f991" - integrity sha512-6CLxw83vQf6DKqXxMPwl8qpF8I7THFZuIwLt4TnNsumxkp1VsRZWT8txQxncT/Rl2UojTsFzWgDG4FRMwafrlA== +"@types/node@^12.20.19": + version "12.20.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.19.tgz#538e61fc220f77ae4a4663c3d8c3cb391365c209" + integrity sha512-niAuZrwrjKck4+XhoCw6AAVQBENHftpXw9F4ryk66fTgYaKQ53R4FI7c9vUGGw5vQis1HKBHDR1gcYI/Bq1xvw== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -7208,12 +7208,12 @@ jest-message-util@^26.6.0, jest-message-util@^26.6.2: slash "^3.0.0" stack-utils "^2.0.2" -jest-mock-extended@^1.0.18: - version "1.0.18" - resolved "https://registry.yarnpkg.com/jest-mock-extended/-/jest-mock-extended-1.0.18.tgz#27a40e882c09f8230243fc6765fe7285b03f2b4b" - integrity sha512-qf1n7lIa2dTxxPIBr+FlXrbj3hnV1sG9DPZsrr2H/8W+Jw0wt6OmeOQsPcjRuW8EXIECC9pDXsSIfEdn+HP7JQ== +jest-mock-extended@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/jest-mock-extended/-/jest-mock-extended-2.0.1.tgz#5cc5085c2a3a83e301fd0eeba9ac82af4b3dc389" + integrity sha512-fOfes4i6a5991ZFzj9Un8nlFsSm2lpnJ9jRm6eT3kdtW8Bq9jdQiPYiCE2MHDiU5ySIbjzN4UkhCLAJ1jVtkaQ== dependencies: - ts-essentials "^7.0.2" + ts-essentials "^7.0.3" jest-mock@^26.6.2: version "26.6.2" @@ -11878,10 +11878,10 @@ tryer@^1.0.1: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== -ts-essentials@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.2.tgz#e21142df8034dbd444cb9573ed204d0b85fc64fb" - integrity sha512-qWPVC1xZGdefbsgFP7tPo+bsgSA2ZIXL1XeEe5M2WoMZxIOr/HbsHxP/Iv75IFhiMHMDGL7cOOwi5SXcgx9mHw== +ts-essentials@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" + integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== ts-pnp@1.2.0, ts-pnp@^1.1.6: version "1.2.0"