Skip to content

Commit

Permalink
feat: Add a toggle between hex and base64 (#62)
Browse files Browse the repository at this point in the history
A lot less rewrite -> same feature of toggle. Also makes use of session
storage instead of chrome storage so we don't request extra permissions
from the users, and is more lightweight and easier to access.
  • Loading branch information
gvking committed Apr 11, 2023
1 parent 044dc24 commit 7fa1a98
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 19 deletions.
28 changes: 28 additions & 0 deletions log-window.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,30 @@
right: 10px;
}

#base64-radio-input {
position: fixed;
top: 70px;
right: 10px;
}

#base64-radio-input-label {
position: fixed;
top: 70px;
right: 40px;
}

#hex-radio-input {
position: fixed;
top: 100px;
right: 10px;
}

#hex-radio-input-label {
position: fixed;
top: 100px;
right: 40px;
}

h3 {
padding-top: 1em;
}
Expand Down Expand Up @@ -58,6 +82,10 @@ <h1>EME Method Call and Event Log</h1>
<p>Some personally identifiable information may be in the log. Be careful about posting the log on bug reports.</p>
<button id="clear-button">Clear log</button>
<a id="download-button" download="EMELogFile.txt"><button>Download log</button></a>
<input type="radio" id="hex-radio-input" name="radio-toggle-group" value = "hex" checked>
<label for="hex" id="hex-radio-input-label">Hex</label>
<input type="radio" id="base64-radio-input" name="radio-toggle-group" value = "base64">
<label for="base64" id="base64-radio-input-label">Base64</label>
<ul id="eme-log"></ul>
</body>
</html>
67 changes: 50 additions & 17 deletions log-window.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,24 @@ class EmeLoggerWindow {
this.downloadButton_ = document.querySelector('#download-button');
this.downloadButton_.addEventListener('click', () => {
// Format the logs into a Blob.
const blob = new Blob([this.textLogs_], { type: 'text/plain' });
const blob = new Blob([this.textLogs_], {type: 'text/plain'});

// Trigger a download.
chrome.downloads.download({
url: URL.createObjectURL(blob),
filename: 'EMELogFile.txt'
});
chrome.downloads.download(
{url: URL.createObjectURL(blob), filename: 'EMELogFile.txt'});
});

// Default to hex first as that is what is selected.
sessionStorage.setItem('toggle', 'hex');
let contact = document.querySelectorAll('input[name="radio-toggle-group"]');

/** @private {!HTMLInputElement} */
for (let i = 0; i < contact.length; i++) {
contact[i].addEventListener('change', function() {
let val = this.value;
sessionStorage.setItem('toggle', this.value);
});
}
}

/**
Expand Down Expand Up @@ -143,21 +153,34 @@ class EmeLoggerWindow {
}

// TODO: Keep an array of blobs instead? More efficient for large logs?
this.textLogs_ +=
formattedTimestamp + '\n\n' +
instanceId.textContent + '\n' +
data.textContent + '\n\n\n\n';
this.textLogs_ += formattedTimestamp + '\n\n' + instanceId.textContent +
'\n' + data.textContent + '\n\n\n\n';
}

/**
* @param {number} byte
* @return {string}
* @private
*/
byteToHex_(byte) {
byteToHex(byte) {
return '0x' + byte.toString(16).padStart(2, '0');
}

/**
* @param {number} byte
* @return {string}
*/
bytesToBase64(bytes) {
return btoa(String.fromCharCode.apply(null, new Uint8Array(bytes)));
}

/**
* @return {string}
* @private
*/
toggleStoredInSessionStorage_() {
return sessionStorage.getItem('toggle');
}

/**
* @param {*} obj
* @param {string} indentation
Expand Down Expand Up @@ -185,12 +208,22 @@ class EmeLoggerWindow {
if (data.length == 0) {
format += '[]';
} else {
format += ' ' + '[\n';
while (data.length) {
const row = data.splice(0, 16);
format += indentation + ' ';
format += row.map(this.byteToHex_).join(', ');
format += ',\n';
format += ' ' +
'[\n';
if (this.toggleStoredInSessionStorage_() == 'hex') {
while (data.length) {
const row = data.splice(0, 16);
format += indentation + ' ';
format += row.map(this.byteToHex).join(', ');
format += ',\n';
}
} else {
const base64data =
this.bytesToBase64(data).split(/(.{97})/).filter(O => O);
base64data.forEach(base64chunk => {
format += base64chunk;
format += '\n';
})
}
format += indentation + ']';
}
Expand Down
61 changes: 59 additions & 2 deletions spec/log-window-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ describe('Log window', () => {
let mockLogElement;
let mockClearButton;
let mockDownloadButton;
let mockToggleToHexRadioButton;
let mockToggleToBase64RadioButton;

beforeAll(() => {
mockDocument = document.createElement('div');
Expand Down Expand Up @@ -51,6 +53,22 @@ describe('Log window', () => {
mockDownloadButton.style.display = 'none';
mockDocument.appendChild(mockDownloadButton);

// Add mock radio
mockToggleToHexRadioButton = document.createElement('input');
mockToggleToHexRadioButton.checked = 'true';
mockToggleToHexRadioButton.type = 'radio';
mockToggleToHexRadioButton.id = 'hex-radio-input';
mockToggleToHexRadioButton.name = 'radio-toggle-group';
mockToggleToHexRadioButton.value = 'hex';
mockDocument.appendChild(mockToggleToHexRadioButton);

mockToggleToBase64RadioButton = document.createElement('input');
mockToggleToBase64RadioButton.type = 'radio';
mockToggleToBase64RadioButton.id = 'base64-radio-input';
mockToggleToBase64RadioButton.name = 'radio-toggle-group';
mockToggleToBase64RadioButton.value = 'base64';
mockDocument.appendChild(mockToggleToBase64RadioButton);

// Reset the singleton we're testing.
EmeLoggerWindow.instance = new EmeLoggerWindow();
});
Expand Down Expand Up @@ -142,7 +160,7 @@ describe('Log window', () => {
type: TraceAnything.LogTypes.Event,
className: 'SomeClass',
eventName: 'someevent',
event: fakeObjectWithType('Event', { type: 'someevent' }),
event: fakeObjectWithType('Event', {type: 'someevent'}),
});
expect(mockLogElement.querySelector('.title').textContent)
.toContain('SomeClass someevent Event');
Expand All @@ -156,7 +174,7 @@ describe('Log window', () => {
type: TraceAnything.LogTypes.Event,
className: 'SomeClass',
eventName: 'someevent',
event: fakeObjectWithType('Event', { type: 'someevent' }),
event: fakeObjectWithType('Event', {type: 'someevent'}),
value: 0,
});
expect(mockLogElement.querySelector('.data').textContent)
Expand Down Expand Up @@ -289,6 +307,45 @@ describe('Log window', () => {
const objectText = text.split('=> MediaKeySession instance ')[1];
expect(JSON5.parse(objectText)).toEqual(fields);
});

it('builds a formatted string with Hex', () => {
const fakeLicenseResponse = 23;
const fakeLicenseResponseInHex =
EmeLoggerWindow.instance.byteToHex(fakeLicenseResponse);

const fieldsHex = {
type: TraceAnything.LogTypes.Method,
className: 'MediaKeySession',
methodName: 'update',
args: [fakeLicenseResponseInHex],
};
const objectHex = fakeObjectWithType('MediaKeySession', fieldsHex);
logResult(objectHex);

const textWithHex = mockLogElement.querySelector('.data').textContent;

// 23 in decimal -> hex is 0x17.
expect(textWithHex).toContain('0x17');
});

it('builds a formatted string with Base64', () => {
const fakeLicenseResponse = new Uint8Array([23]);
const fakeLicenseResponseInBase64 =
EmeLoggerWindow.instance.bytesToBase64(fakeLicenseResponse);
const fieldsBase64 = {
type: TraceAnything.LogTypes.Method,
className: 'MediaKeySession',
methodName: 'update',
args: [fakeLicenseResponseInBase64],
};
const objectBase64 = fakeObjectWithType('MediaKeySession', fieldsBase64);
logResult(objectBase64);

const textWithBase64 = mockLogElement.querySelector('.data').textContent;

// 23 in decimal -> base64 is 'Fw=='.
expect(textWithBase64).toContain('Fw==');
});
});

// This matches the format used in function emeLogger() in
Expand Down

0 comments on commit 7fa1a98

Please sign in to comment.