Skip to content

Commit

Permalink
ChromeOS-AutoStart v3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
supechicken authored Apr 12, 2022
1 parent 8cf46ff commit 32b7764
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 16 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<p align="center"><img src="/icon.png" alt="logo" /></p>
<p align="center">
<img src="/icon-light.png#gh-light-mode-only" alt="logo" />
<img src="/icon-dark.png#gh-dark-mode-only" alt="logo" />
</p>
<h1 align="center">ChromeOS Autostart</h1>

## An extension for running shell command at ChromeOS startup automatically without removing RootFS verification.
Expand All @@ -12,6 +15,8 @@
- A new window will appear and type the command you want to run it at startup
- Optional: Click the `Test` button to test it out after setting a command

<em>* Please do not delete the unzipped folder after loading the extension, otherwise the extension will not work</em>

## How does it works?

There is a Chrome extension API called `chrome.terminalPrivate` which can be used to execute crosh commands (and shell commands), and it is only available on some extensions that made by Google (Secure Shell, Chromebook Recovery Utility, etc). However, we can use one of those extension's ID key to get the access of that API. (this extension used the key from Secure Shell)
Expand Down
17 changes: 14 additions & 3 deletions background.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
// dark mode icon handler
chrome.runtime.onMessage.addListener( (e) => {
if (e.scheme == 'dark') {
chrome.browserAction.setIcon({ path: '/icon-dark_38x38.png' });
}
});

// open run.html (used to execute command via terminalPrivate API) at login
chrome.runtime.onStartup.addListener( () => {
chrome.windows.create({url: "/run.html", type: 'popup', state: 'minimized'})
chrome.windows.create({url: "run.html", type: 'popup', state: 'minimized', height: 200, width: 200})
});

// prompt user to enter a command after install
chrome.runtime.onInstalled.addListener( (i) => {
if (i.reason == 'install') {
chrome.windows.create({url: '/option.html', type: 'popup', height: 221, width: 230})
}})
chrome.windows.create({url: 'option.html', type: 'popup', height: 300, width: 310})
}
});
5 changes: 5 additions & 0 deletions dark-mode-icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// a content script for setting dark mode icon
// see https://stackoverflow.com/questions/58880234/toggle-chrome-extension-icon-based-on-light-or-dark-mode-browser
if ( window.matchMedia('(prefers-color-scheme: dark)').matches ) {
chrome.runtime.sendMessage({ scheme: 'dark' })
}
Binary file added icon-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icon-dark_38x38.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added icon-light_38x38.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 9 additions & 3 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
{
"manifest_version": 2,
"name": "ChromeOS Autostart",
"version": "2.2.1",
"icons": { "170": "icon.png" },
"version": "3.0",
"icons": { "170": "icon-light.png" },
"description": "Run shell command at ChromeOS startup.",
"background": {
"scripts": [ "background.js" ]
},
"content_scripts": [
{
"matches": [ "<all_urls>" ],
"js": [ "/dark-mode-icon.js" ]
}
],
"browser_action": {
"default_icon": {
"170": "icon.png"
"38": "icon-light_38x38.png"
},
"default_title": "ChromeOS AutoStart",
"default_popup": "option.html"
Expand Down
13 changes: 8 additions & 5 deletions option.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
<!-- option.html: option page -->
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div style='text-align: center;'>
<p id='current_cmd' />
<br />
<p>Enter the command you wish to run at startup:</p>
<input name='new_cmd' type='text' id='new_cmd'/><br />
<input name='submit' type='button' id='enter' value='Enter'/><br />
<input name='clear' type='button' id='clear' value='Clear existing startup command'/><br />
<input name='test' type='button' id='test' value='Test'/>
<label><input name='debug' type='checkbox' id='debug' value='Debug'>Debug mode</label>
<input name='new_cmd' type='text' id='new_cmd' placeholder="Command here"/><button id='enter'>Enter</button><br />
<button id='clear'>Clear existing startup command</button><br />
<button id='test'>Test</button>
<input name='debug' type='checkbox' id='debug' />
<label for='debug'>Debug mode</label>
</div>
</body>
<script src='/option.js'></script>
Expand Down
2 changes: 1 addition & 1 deletion option.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ document.getElementById('clear').onclick = function() {
}

document.getElementById('test').onclick = function() {
chrome.windows.create({url: '/run.html', type: 'popup'});
chrome.windows.create({url: '/run.html', type: 'popup', height: 200, width: 200});
};
7 changes: 6 additions & 1 deletion run.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<!-- run.html: wrapper for run.js -->

<html>
<script src='/run.js'></script>
<head>
<link rel="stylesheet" href="style.css">
<script src='/run.js'></script>
</head>
<body>
</body>
</html>
16 changes: 14 additions & 2 deletions run.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@

chrome.storage.local.get('debug', (debug) => {
chrome.storage.local.get('start', (cmd) => {
chrome.terminalPrivate.onProcessOutput.addListener( (pid, type, output) => {
chrome.terminalPrivate.onProcessOutput.addListener( (pid, type, data) => {
let output
// on Chrome OS 100+, the onProcessOutput function will return an ArrayBuffer object instead of a string,
// we need to convert it to string if an ArrayBuffer is returned.
//
// For more info, see https://chromium-review.googlesource.com/c/apps/libapps/+/3470612/
if (data instanceof ArrayBuffer) {
let dec = new TextDecoder('utf-8')
output = dec.decode(data)
} else {
output = data
}

// print terminal output in console
if (output.split("\n").includes("__ext_close__\r") && !debug.debug) {
if (output.match(/[^"]__ext_close__/) && !debug.debug) {
// close terminal process
chrome.terminalPrivate.closeTerminalProcess(pid);

Expand Down
53 changes: 53 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
body {
height: 300px;
width: 300px;
}

button, input, body {
font-family: Arial;
font-size: 15px;
margin-bottom: 3px;
margin-right: 2px;
}

button {
background-color: #1a73e8;
color: white;
border-radius: 4px;
padding: 5px 10px;
border: none;
cursor: pointer;
}

button:hover {
opacity: 0.9;
}

input[type="text"] {
height: 25px;
border: 2px solid;
border-radius: 4px;
}

@media (prefers-color-scheme: light) {
body, input[type="text"], textarea {
background-color: #fff;
color: #000
}
input[type="text"], textarea {
border-color: rgb(0, 0, 0);
}
}

@media (prefers-color-scheme: dark) {
body, input[type="text"], textarea {
background-color: #1e1e1e;
color: rgb(199, 199, 199);
}
input[type="text"], textarea {
border-color: rgb(199, 199, 199);
}
::placeholder {
color: rgb(183, 183, 183);
}
}

0 comments on commit 32b7764

Please sign in to comment.