[hardware test] Use a BankViewController

And add a SerialNumberController
This commit is contained in:
Romain Goyet
2018-05-04 15:53:53 +02:00
committed by Ecco
parent 69545b9cf9
commit 71f9ce3b67
16 changed files with 250 additions and 55 deletions

View File

@@ -2,6 +2,7 @@ app_objs += $(addprefix apps/hardware_test/,\
app.o\
arrow_view.o\
battery_test_controller.o\
code_128b_view.o\
keyboard_test_controller.o\
keyboard_view.o\
led_test_controller.o\
@@ -11,6 +12,7 @@ app_objs += $(addprefix apps/hardware_test/,\
reset_controller.o\
screen_test_controller.o\
screen_test_controller.o\
serial_number_controller.o\
usb_test_controller.o\
)

View File

@@ -17,27 +17,48 @@ App::Descriptor * App::Snapshot::descriptor() {
}
App::App(Container * container, Snapshot * snapshot) :
::App(container, snapshot, &m_keyboardController),
m_keyboardController(&m_modalViewController),
m_USBTestController(nullptr)
::App(container, snapshot, &m_wizardViewController),
m_wizardViewController(&m_modalViewController)
{
}
ViewController * App::USBController() {
return &m_USBTestController;
App::WizardViewController::WizardViewController(Responder * parentResponder) :
BankViewController(parentResponder),
m_keyboardController(this),
m_screenTestController(this),
m_ledTestController(this),
m_batteryTestController(this),
m_USBTestController(this),
m_serialNumberController(this),
m_resetController(this)
{
}
int App::numberOfTimers() {
return firstResponder() == &m_USBTestController;
int App::WizardViewController::numberOfChildren() {
return 7;
}
Timer * App::timerAtIndex(int i) {
assert(i == 0);
return &m_USBTestController;
ViewController * App::WizardViewController::childAtIndex(int i) {
ViewController * children[] = {
&m_keyboardController,
&m_screenTestController,
&m_ledTestController,
&m_batteryTestController,
&m_USBTestController,
&m_serialNumberController,
&m_resetController
};
return children[i];
}
bool App::processEvent(Ion::Events::Event e) {
::App::processEvent(e);
bool App::WizardViewController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OnOff) {
return false;
}
if (activeIndex() >= numberOfChildren()) {
return false;
}
setActiveIndex(activeIndex() + 1);
return true;
}

View File

@@ -2,8 +2,13 @@
#define HARDWARE_TEST_APP_H
#include <escher.h>
#include "usb_test_controller.h"
#include "keyboard_test_controller.h"
#include "screen_test_controller.h"
#include "led_test_controller.h"
#include "battery_test_controller.h"
#include "usb_test_controller.h"
#include "serial_number_controller.h"
#include "reset_controller.h"
class AppsContainer;
@@ -16,14 +21,25 @@ public:
App * unpack(Container * container) override;
Descriptor * descriptor() override;
};
ViewController * USBController();
int numberOfTimers() override;
Timer * timerAtIndex(int i) override;
bool processEvent(Ion::Events::Event e) override;
private:
class WizardViewController : public BankViewController {
public:
WizardViewController(Responder * parentResponder);
int numberOfChildren() override;
ViewController * childAtIndex(int i) override;
bool handleEvent(Ion::Events::Event event) override;
private:
KeyboardTestController m_keyboardController;
ScreenTestController m_screenTestController;
LEDTestController m_ledTestController;
BatteryTestController m_batteryTestController;
USBTestController m_USBTestController;
SerialNumberController m_serialNumberController;
ResetController m_resetController;
};
App(Container * container, Snapshot * snapshot);
KeyboardTestController m_keyboardController;
USBTestController m_USBTestController;
WizardViewController m_wizardViewController;
};
}

View File

@@ -23,9 +23,8 @@ View * BatteryTestController::view() {
bool BatteryTestController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK) {
if (strcmp(m_view.batteryStateTextView()->text(), k_batteryOKText) == 0) {
ModalViewController * modal = (ModalViewController *)parentResponder();
App * a = (App *)app();
modal->displayModalViewController(a->USBController(), 0.0f, 0.0f);
// Handled in WizardViewController
return false;
}
}
updateBatteryState(Ion::Battery::voltage(), Ion::Battery::isCharging());

View File

@@ -0,0 +1,100 @@
#include "code_128b_view.h"
namespace HardwareTest {
constexpr uint16_t patterns[] = {0x6CC, 0x66C, 0x666, 0x498, 0x48C, 0x44C, 0x4C8, 0x4C4, 0x464, 0x648, 0x644, 0x624, 0x59C, 0x4DC, 0x4CE, 0x5CC, 0x4EC, 0x4E6, 0x672, 0x65C, 0x64E, 0x6E4, 0x674, 0x76E, 0x74C, 0x72C, 0x726, 0x764, 0x734, 0x732, 0x6D8, 0x6C6, 0x636, 0x518, 0x458, 0x446, 0x588, 0x468, 0x462, 0x688, 0x628, 0x622, 0x5B8, 0x58E, 0x46E, 0x5D8, 0x5C6, 0x476, 0x776, 0x68E, 0x62E, 0x6E8, 0x6E2, 0x6EE, 0x758, 0x746, 0x716, 0x768, 0x762, 0x71A, 0x77A, 0x642, 0x78A, 0x530, 0x50C, 0x4B0, 0x486, 0x42C, 0x426, 0x590, 0x584, 0x4D0, 0x4C2, 0x434, 0x432, 0x612, 0x650, 0x7BA, 0x614, 0x47A, 0x53C, 0x4BC, 0x49E, 0x5E4, 0x4F4, 0x4F2, 0x7A4, 0x794, 0x792, 0x6DE, 0x6F6, 0x7B6, 0x578, 0x51E, 0x45E, 0x5E8, 0x5E2, 0x7A8, 0x7A2, 0x5DE, 0x5EE, 0x75E, 0x7AE};
constexpr uint16_t startPattern = 0x690;
constexpr uint16_t stopPattern = 0x18EB;
Code128BView::Code128BView() :
View(),
m_moduleWidth(0),
m_data(nullptr)
{
}
void Code128BView::setData(const char * data) {
m_data = data;
markRectAsDirty(bounds());
}
void Code128BView::layoutSubviews() {
updateModuleWidth();
}
void Code128BView::updateModuleWidth() {
if (m_data == nullptr) {
m_moduleWidth = 0;
return;
}
int numberOfModules =
10 + // quiet zone
11 + // start
11 * strlen(m_data) + // data
11 + // checksum
13; // stop
m_moduleWidth = bounds().width() / numberOfModules;
}
void Code128BView::drawQuietZoneAt(KDContext * ctx, KDCoordinate * x) const {
ctx->fillRect(KDRect(*x, 0, 10*m_moduleWidth, bounds().height()), KDColorWhite);
*x = *x + 10*m_moduleWidth;
}
void Code128BView::drawPatternAt(KDContext * ctx, uint16_t pattern, KDCoordinate * x, KDCoordinate width) const {
assert(width <= 16);
for (int i=0; i<width; i++) {
if (pattern & (1<<(width-i-1))) {
ctx->fillRect(KDRect(*x, 0, m_moduleWidth, bounds().height()), KDColorBlack);
}
*x = *x + m_moduleWidth;
}
}
void Code128BView::drawCharAt(KDContext * ctx, char c, KDCoordinate * x) const {
return drawPatternAt(ctx, patterns[c-32], x);
}
int Code128BView::checksum() const {
int checksum = 104;
const char * letter = m_data;
int i = 1;
while (*letter != 0) {
checksum += (*letter - 32)*i;
i++;
letter++;
}
return checksum % 103;
}
// Serial Number is 96 bits = 4 * 24 bits = 4 * 4 letters in Base64 = 16 letters
void Code128BView::drawRect(KDContext * ctx, KDRect rect) const {
if (m_moduleWidth == 0) {
// Not enough space for given string
ctx->fillRect(rect, KDColorRed);
return;
}
ctx->fillRect(rect, KDColorWhite);
KDCoordinate x = 0;
drawQuietZoneAt(ctx, &x);
drawPatternAt(ctx, startPattern, &x);
const char * letter = m_data;
while (*letter != 0) {
drawCharAt(ctx, *letter, &x);
letter++;
}
drawPatternAt(ctx, patterns[checksum()], &x);
drawPatternAt(ctx, stopPattern, &x, 13);
drawQuietZoneAt(ctx, &x);
ctx->drawString(m_data, KDPointZero);
}
}

View File

@@ -0,0 +1,28 @@
#ifndef HARDWARE_TEST_CODE_128B_VIEW_H
#define HARDWARE_TEST_CODE_128B_VIEW_H
#include <escher.h>
namespace HardwareTest {
class Code128BView : public View {
public:
Code128BView();
void drawRect(KDContext * ctx, KDRect rect) const override;
void setData(const char * data);
void layoutSubviews() override;
private:
static constexpr KDCoordinate charPatternWidth = 11;
void updateModuleWidth();
int checksum() const;
void drawQuietZoneAt(KDContext * ctx, KDCoordinate * x) const;
void drawPatternAt(KDContext * ctx, uint16_t pattern, KDCoordinate * x, KDCoordinate width = charPatternWidth) const;
void drawCharAt(KDContext * ctx, char c, KDCoordinate * x) const;
int m_moduleWidth;
const char * m_data;
};
}
#endif

View File

@@ -10,8 +10,7 @@ namespace HardwareTest {
KeyboardTestController::KeyboardTestController(Responder * parentResponder) :
ViewController(parentResponder),
m_keyboardView(),
m_screenTestController(nullptr)
m_keyboardView()
{
}
@@ -25,8 +24,8 @@ bool KeyboardTestController::handleEvent(Ion::Events::Event event) {
if (state == onlyKeyDown) {
m_keyboardView.setTestedKeyIndex(m_keyboardView.testedKeyIndex()+1);
if (m_keyboardView.testedKeyIndex() == Ion::Keyboard::NumberOfValidKeys) {
ModalViewController * modal = (ModalViewController *)parentResponder();
modal->displayModalViewController(&m_screenTestController, 0.0f, 0.0f);
// Returning false will go to the next step in the WizardViewController
return false;
}
}
return true;

View File

@@ -3,7 +3,6 @@
#include <escher.h>
#include "keyboard_view.h"
#include "screen_test_controller.h"
namespace HardwareTest {
@@ -15,7 +14,6 @@ public:
void viewWillAppear() override;
private:
KeyboardView m_keyboardView;
ScreenTestController m_screenTestController;
};
}

View File

@@ -10,8 +10,7 @@ constexpr KDColor LEDTestController::k_LEDColors[k_numberOfColors];
LEDTestController::LEDTestController(Responder * parentResponder) :
ViewController(parentResponder),
m_view(),
m_LEDColorIndex(0),
m_batteryTestController(this)
m_LEDColorIndex(0)
{
}
@@ -23,8 +22,8 @@ bool LEDTestController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK) {
setLEDColor(LEDColorAtIndex(m_LEDColorIndex++));
if (m_LEDColorIndex == k_numberOfColors) {
ModalViewController * modal = (ModalViewController *)parentResponder();
modal->displayModalViewController(&m_batteryTestController, 0.0f, 0.0f);
// Next step, see WizardViewController
return false;
}
}
return true;

View File

@@ -2,7 +2,6 @@
#define HARDWARE_TEST_LED_TEST_CONTROLLER_H
#include <escher.h>
#include "battery_test_controller.h"
#include "arrow_view.h"
namespace HardwareTest {
@@ -37,7 +36,6 @@ private:
static KDColor LEDColorAtIndex(int i);
ContentView m_view;
int m_LEDColorIndex;
BatteryTestController m_batteryTestController;
};
}

View File

@@ -8,8 +8,7 @@ namespace HardwareTest {
ScreenTestController::ScreenTestController(Responder * parentResponder) :
ViewController(parentResponder),
m_patternIndex(0),
m_view(),
m_ledTestController(this)
m_view()
{
}
@@ -22,8 +21,8 @@ bool ScreenTestController::handleEvent(Ion::Events::Event event) {
return true;
}
if (m_patternIndex == Pattern::numberOfPatterns()) {
ModalViewController * modal = (ModalViewController *)parentResponder();
modal->displayModalViewController(&m_ledTestController, 0.0f, 0.0f);
// Go to the next step - this will be handled by the WizardViewController
return false;
} else {
showNextPattern();
}

View File

@@ -2,7 +2,6 @@
#define HARDWARE_TEST_SCREEN_TEST_CONTROLLER_H
#include <escher.h>
#include "led_test_controller.h"
#include "pattern_view.h"
#include "pattern.h"
@@ -18,7 +17,6 @@ private:
void showNextPattern();
int m_patternIndex;
PatternView m_view;
LEDTestController m_ledTestController;
};
}

View File

@@ -0,0 +1,25 @@
#include "serial_number_controller.h"
#include <ion.h>
namespace HardwareTest {
SerialNumberController::SerialNumberController(Responder * parentResponder) :
ViewController(parentResponder),
m_barCodeView()
{
}
void SerialNumberController::viewWillAppear() {
static char serialNumber[24];
Ion::getSerialNumber(serialNumber);
m_barCodeView.setData(serialNumber);
}
bool SerialNumberController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OnOff || event == Ion::Events::OK) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,22 @@
#ifndef HARDWARE_TEST_SERIAL_NUMBER_CONTROLLER_H
#define HARDWARE_TEST_SERIAL_NUMBER_CONTROLLER_H
#include <escher.h>
#include "code_128b_view.h"
namespace HardwareTest {
class SerialNumberController : public ViewController {
public:
SerialNumberController(Responder * parentResponder);
View * view() override { return &m_barCodeView; }
bool handleEvent(Ion::Events::Event event) override;
void viewWillAppear() override;
private:
Code128BView m_barCodeView;
};
}
#endif

View File

@@ -10,10 +10,8 @@ namespace HardwareTest {
USBTestController::USBTestController(Responder * parentResponder) :
ViewController(parentResponder),
Timer(1),
m_view(),
m_shouldPlugUSB(true),
m_resetController(this)
m_shouldPlugUSB(true)
{
}
@@ -22,10 +20,6 @@ View * USBTestController::view() {
}
bool USBTestController::handleEvent(Ion::Events::Event e) {
return true;
}
bool USBTestController::fire() {
if (Ion::USB::isPlugged() && m_shouldPlugUSB) {
m_view.USBTextView()->setText(k_USBUnplugText);
m_view.arrowView()->setDirection(false);
@@ -34,11 +28,10 @@ bool USBTestController::fire() {
return true;
}
if (!Ion::USB::isPlugged() && !m_shouldPlugUSB) {
ModalViewController * modal = (ModalViewController *)parentResponder();
modal->displayModalViewController(&m_resetController, 0.0f, 0.0f);
return true;
// We're done, tell WizardViewController to go to the next step
return false;
}
return false;
return true;
}
void USBTestController::viewWillAppear() {

View File

@@ -2,19 +2,18 @@
#define HARDWARE_TEST_USB_TEST_CONTROLLER_H
#include <escher.h>
#include "reset_controller.h"
#include "arrow_view.h"
namespace HardwareTest {
class USBTestController : public ViewController, public Timer {
class USBTestController : public ViewController {
public:
USBTestController(Responder * parentResponder);
View * view() override;
void viewWillAppear() override;
bool handleEvent(Ion::Events::Event e) override;
private:
bool fire() override;
//bool fire() override;
class ContentView : public SolidColorView {
public:
ContentView();
@@ -40,7 +39,6 @@ private:
constexpr static const char * k_USBUnplugText = "OK, UNPLUG USB";
ContentView m_view;
bool m_shouldPlugUSB;
ResetController m_resetController;
};
}