13 changed files with 390 additions and 0 deletions
@ -0,0 +1,4 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="PublishConfigData" serverName="Homeserver" /> |
||||||
|
</project> |
@ -0,0 +1,9 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<module version="4"> |
||||||
|
<component name="NewModuleRootManager"> |
||||||
|
<content url="file://$MODULE_DIR$" /> |
||||||
|
<orderEntry type="inheritedJdk" /> |
||||||
|
<orderEntry type="sourceFolder" forTests="false" /> |
||||||
|
<orderEntry type="library" name="jquery" level="application" /> |
||||||
|
</component> |
||||||
|
</module> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="JavaScriptLibraryMappings"> |
||||||
|
<file url="PROJECT" libraries="{jquery}" /> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,8 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="ProjectModuleManager"> |
||||||
|
<modules> |
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/html.iml" filepath="$PROJECT_DIR$/.idea/html.iml" /> |
||||||
|
</modules> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="VcsDirectoryMappings"> |
||||||
|
<mapping directory="$PROJECT_DIR$/shield-remote" vcs="Git" /> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,25 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="ProjectTasksOptions"> |
||||||
|
<TaskOptions isEnabled="false"> |
||||||
|
<option name="arguments" value="$FileName$:$FileNameWithoutExtension$.css" /> |
||||||
|
<option name="checkSyntaxErrors" value="true" /> |
||||||
|
<option name="description" /> |
||||||
|
<option name="exitCodeBehavior" value="ERROR" /> |
||||||
|
<option name="fileExtension" value="scss" /> |
||||||
|
<option name="immediateSync" value="true" /> |
||||||
|
<option name="name" value="SCSS" /> |
||||||
|
<option name="output" value="$FileNameWithoutExtension$.css:$FileNameWithoutExtension$.css.map" /> |
||||||
|
<option name="outputFilters"> |
||||||
|
<array /> |
||||||
|
</option> |
||||||
|
<option name="outputFromStdout" value="false" /> |
||||||
|
<option name="program" value="sass" /> |
||||||
|
<option name="runOnExternalChanges" value="true" /> |
||||||
|
<option name="scopeName" value="Current File" /> |
||||||
|
<option name="trackOnlyRoot" value="true" /> |
||||||
|
<option name="workingDir" value="$FileDir$" /> |
||||||
|
<envs /> |
||||||
|
</TaskOptions> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,87 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="AutoImportSettings"> |
||||||
|
<option name="autoReloadType" value="SELECTIVE" /> |
||||||
|
</component> |
||||||
|
<component name="ChangeListManager"> |
||||||
|
<list default="true" id="770ea386-39b9-422e-9e8d-15b616f9ec1c" name="Default Changelist" comment="" /> |
||||||
|
<option name="SHOW_DIALOG" value="false" /> |
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" /> |
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> |
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" /> |
||||||
|
</component> |
||||||
|
<component name="ComposerSettings"> |
||||||
|
<execution /> |
||||||
|
</component> |
||||||
|
<component name="FileTemplateManagerImpl"> |
||||||
|
<option name="RECENT_TEMPLATES"> |
||||||
|
<list> |
||||||
|
<option value="CSS File" /> |
||||||
|
<option value="JavaScript File" /> |
||||||
|
</list> |
||||||
|
</option> |
||||||
|
</component> |
||||||
|
<component name="Git.Settings"> |
||||||
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/shield-remote" /> |
||||||
|
</component> |
||||||
|
<component name="PhpDebugGeneral" listening_started="true" /> |
||||||
|
<component name="ProjectId" id="1knpyvR38KQ5CcG0946GdBJ6dRs" /> |
||||||
|
<component name="ProjectLevelVcsManager" settingsEditedManually="true" /> |
||||||
|
<component name="ProjectViewState"> |
||||||
|
<option name="hideEmptyMiddlePackages" value="true" /> |
||||||
|
<option name="showLibraryContents" value="true" /> |
||||||
|
</component> |
||||||
|
<component name="PropertiesComponent"> |
||||||
|
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> |
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" /> |
||||||
|
<property name="list.type.of.created.stylesheet" value="CSS" /> |
||||||
|
<property name="settings.editor.selected.configurable" value="watcher.settings" /> |
||||||
|
<property name="vue.rearranger.settings.migration" value="true" /> |
||||||
|
</component> |
||||||
|
<component name="RecentsManager"> |
||||||
|
<key name="MoveFile.RECENT_KEYS"> |
||||||
|
<recent name="$PROJECT_DIR$" /> |
||||||
|
</key> |
||||||
|
</component> |
||||||
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" /> |
||||||
|
<component name="TaskManager"> |
||||||
|
<task active="true" id="Default" summary="Default task"> |
||||||
|
<changelist id="770ea386-39b9-422e-9e8d-15b616f9ec1c" name="Default Changelist" comment="" /> |
||||||
|
<created>1606346468032</created> |
||||||
|
<option name="number" value="Default" /> |
||||||
|
<option name="presentableId" value="Default" /> |
||||||
|
<updated>1606346468032</updated> |
||||||
|
<workItem from="1606346469059" duration="5052000" /> |
||||||
|
</task> |
||||||
|
<servers /> |
||||||
|
</component> |
||||||
|
<component name="TypeScriptGeneratedFilesManager"> |
||||||
|
<option name="version" value="3" /> |
||||||
|
</component> |
||||||
|
<component name="WindowStateProjectService"> |
||||||
|
<state x="317" y="133" width="722" height="459" key="EditFileWatcherDialog" timestamp="1606348204010"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state x="317" y="133" width="722" height="459" key="EditFileWatcherDialog/0.0.1366.720@0.0.1366.720" timestamp="1606348204010" /> |
||||||
|
<state x="478" y="281" width="399" height="163" key="NewPhpFileDialog" timestamp="1606349091045"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state x="478" y="281" width="399" height="163" key="NewPhpFileDialog/0.0.1366.720@0.0.1366.720" timestamp="1606349091045" /> |
||||||
|
<state x="172" y="0" key="SettingsEditor" timestamp="1606348206869"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state x="172" y="0" key="SettingsEditor/0.0.1366.720@0.0.1366.720" timestamp="1606348206869" /> |
||||||
|
<state x="347" y="155" key="run.anything.popup" timestamp="1606347435018"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state x="347" y="155" key="run.anything.popup/0.0.1366.720@0.0.1366.720" timestamp="1606347435018" /> |
||||||
|
<state x="346" y="41" width="672" height="678" key="search.everywhere.popup" timestamp="1606350711537"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state x="346" y="41" width="672" height="678" key="search.everywhere.popup/0.0.1366.720@0.0.1366.720" timestamp="1606350711537" /> |
||||||
|
<state x="403" y="269" width="540" height="192" key="vcs.readOnlyHandler.ReadOnlyStatusDialog" timestamp="1606346509232"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state x="403" y="269" width="540" height="192" key="vcs.readOnlyHandler.ReadOnlyStatusDialog/0.0.1366.720@0.0.1366.720" timestamp="1606346509232" /> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,90 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
const ADB_KEYCODES = array( |
||||||
|
"UNKNOWN" => 0, |
||||||
|
// "MENU" => 1, |
||||||
|
"SOFT_RIGHT" => 2, |
||||||
|
"HOME" => 3, |
||||||
|
"BACK" => 4, |
||||||
|
"CALL" => 5, |
||||||
|
// "ENDCALL" => 6, |
||||||
|
"0" => 7, |
||||||
|
"1" => 8, |
||||||
|
"2" => 9, |
||||||
|
"3" => 10, |
||||||
|
"4" => 11, |
||||||
|
"5" => 12, |
||||||
|
"6" => 13, |
||||||
|
"7" => 14, |
||||||
|
"8" => 15, |
||||||
|
"9" => 16, |
||||||
|
"STAR" => 17, |
||||||
|
"POUND" => 18, |
||||||
|
"DPAD_UP" => 19, |
||||||
|
"DPAD_DOWN" => 20, |
||||||
|
"DPAD_LEFT" => 21, |
||||||
|
"DPAD_RIGHT" => 22, |
||||||
|
"DPAD_CENTER" => 23, |
||||||
|
"VOLUME_UP" => 24, |
||||||
|
"VOLUME_DOWN" => 25, |
||||||
|
"POWER" => 26, |
||||||
|
"CAMERA" => 27, |
||||||
|
"CLEAR" => 28, |
||||||
|
"A" => 29, |
||||||
|
"B" => 30, |
||||||
|
"C" => 31, |
||||||
|
"D" => 32, |
||||||
|
"E" => 33, |
||||||
|
"F" => 34, |
||||||
|
"G" => 35, |
||||||
|
"H" => 36, |
||||||
|
"I" => 37, |
||||||
|
"J" => 38, |
||||||
|
"K" => 39, |
||||||
|
"L" => 40, |
||||||
|
"M" => 41, |
||||||
|
"N" => 42, |
||||||
|
"O" => 43, |
||||||
|
"P" => 44, |
||||||
|
"Q" => 45, |
||||||
|
"R" => 46, |
||||||
|
"S" => 47, |
||||||
|
"T" => 48, |
||||||
|
"U" => 49, |
||||||
|
"V" => 50, |
||||||
|
"W" => 51, |
||||||
|
"X" => 52, |
||||||
|
"Y" => 53, |
||||||
|
"Z" => 54, |
||||||
|
"COMMA" => 55, |
||||||
|
"PERIOD" => 56, |
||||||
|
"ALT_LEFT" => 57, |
||||||
|
"ALT_RIGHT" => 58, |
||||||
|
"SHIFT_LEFT" => 59, |
||||||
|
"SHIFT_RIGHT" => 60, |
||||||
|
"TAB" => 61, |
||||||
|
"SPACE" => 62, |
||||||
|
"SYM" => 63, |
||||||
|
"EXPLORER" => 64, |
||||||
|
"ENVELOPE" => 65, |
||||||
|
"ENTER" => 66, |
||||||
|
"DEL" => 67, |
||||||
|
"GRAVE" => 68, |
||||||
|
"MINUS" => 69, |
||||||
|
"EQUALS" => 70, |
||||||
|
"LEFT_BRACKET" => 71, |
||||||
|
"RIGHT_BRACKET" => 72, |
||||||
|
"BACKSLASH" => 73, |
||||||
|
"SEMICOLON" => 74, |
||||||
|
"APOSTROPHE" => 75, |
||||||
|
"SLASH" => 76, |
||||||
|
"AT" => 77, |
||||||
|
"NUM" => 78, |
||||||
|
// "HEADSETHOOK" => 79, |
||||||
|
"FOCUS" => 80, |
||||||
|
"PLUS" => 81, |
||||||
|
"MENU" => 82, |
||||||
|
"NOTIFICATION" => 83, |
||||||
|
"SEARCH" => 84, |
||||||
|
"TAG_LAST_KEYCODE" => 85, |
||||||
|
); |
@ -0,0 +1,34 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
include_once 'ADBKeyCodes.php'; |
||||||
|
|
||||||
|
class ADBService |
||||||
|
{ |
||||||
|
private $host; |
||||||
|
|
||||||
|
public function __construct($host) |
||||||
|
{ |
||||||
|
$this->host = $host; |
||||||
|
$this->connect(); |
||||||
|
} |
||||||
|
|
||||||
|
public function connect() |
||||||
|
{ |
||||||
|
return $this->executeCommand('connect ' . escapeshellarg($this->host)); |
||||||
|
} |
||||||
|
|
||||||
|
public function disconnect() |
||||||
|
{ |
||||||
|
return $this->executeCommand('disconnect'); |
||||||
|
} |
||||||
|
|
||||||
|
public function executeCommand($command) |
||||||
|
{ |
||||||
|
return shell_exec('adb ' . $command); |
||||||
|
} |
||||||
|
|
||||||
|
public function sendKey($keyIdentifier) |
||||||
|
{ |
||||||
|
return $this->executeCommand(' shell input keyevent ' . ADB_KEYCODES[$keyIdentifier]); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
$axiosRequest = json_decode(file_get_contents('php://input')); |
||||||
|
|
||||||
|
include_once 'ADBService.php'; |
||||||
|
const HOST = '192.168.1.132'; |
||||||
|
|
||||||
|
$service = new ADBService(HOST); |
||||||
|
$service->connect(); |
||||||
|
|
||||||
|
echo json_encode([$service->sendKey($axiosRequest->keyCode)]); |
@ -0,0 +1,102 @@ |
|||||||
|
<!doctype html> |
||||||
|
<html lang="de"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta name="viewport" |
||||||
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
||||||
|
<link rel="stylesheet" href="https://bootswatch.com/4/slate/bootstrap.min.css"> |
||||||
|
<link rel="stylesheet" href="remote.css"> |
||||||
|
<title>Android TV Web Remote</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div class="container"> |
||||||
|
<div class="row" id="remote-control"> |
||||||
|
<a class="col-sm-4 btn btn-danger" onclick="sendKey('POWER')"><i class="fas fa-power-off"></i></a> |
||||||
|
<a class="col-sm-4 btn btn-secondary" onclick="sendKey('DPAD_UP')"><i class="fas fa-caret-up fa-1c5x"></i></a> |
||||||
|
<a class="col-sm-4"></a> |
||||||
|
|
||||||
|
<a class="col-sm-4 btn btn-secondary" onclick="sendKey('DPAD_LEFT')"><i class="fas fa-caret-left fa-1c5x"></i></a> |
||||||
|
<a class="col-sm-4 btn btn-secondary" onclick="sendKey('DPAD_CENTER')">OK</a> |
||||||
|
<a class="col-sm-4 btn btn-secondary" onclick="sendKey('DPAD_RIGHT')"><i class="fas fa-caret-right fa-1c5x"></i></a> |
||||||
|
|
||||||
|
<a class="col-sm-4"></a> |
||||||
|
<a class="col-sm-4 btn btn-secondary" onclick="sendKey('DPAD_DOWN')"><i class="fas fa-caret-down fa-1c5x"></i></a> |
||||||
|
<a class="col-sm-4"></a> |
||||||
|
|
||||||
|
<hr class="col-md-12"/> |
||||||
|
|
||||||
|
<a class="col-sm-4 btn btn-secondary" onclick="sendKey('BACK')"><i class="fas fa-long-arrow-alt-left"></i></a> |
||||||
|
<a class="col-sm-4 btn btn-secondary" onclick="sendKey('HOME')"><i class="fas fa-home"></i></a> |
||||||
|
<a class="col-sm-4 btn btn-secondary" onclick="sendKey('VOLUME_UP')"><i class="fas fa-volume-up"></i></a> |
||||||
|
|
||||||
|
<a class="col-sm-4"></a> |
||||||
|
<a class="col-sm-4"></a> |
||||||
|
<a class="col-sm-4 btn btn-secondary" onclick="sendKey('VOLUME_DOWN')"><i class="fas fa-volume-down"></i></a> |
||||||
|
|
||||||
|
<a class="col-sm-4"></a> |
||||||
|
<a class="col-sm-4"></a> |
||||||
|
<a class="col-sm-4"></a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> |
||||||
|
<script src="https://kit.fontawesome.com/b54a4cceff.js" crossorigin="anonymous"></script> |
||||||
|
<script> |
||||||
|
function sendKey(key) { |
||||||
|
axios.post('execute.php', { |
||||||
|
keyCode: key |
||||||
|
}).then((response) => { |
||||||
|
// console.log(response); |
||||||
|
}).catch((error) => { |
||||||
|
console.log(error); |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// Check for Keypress |
||||||
|
jQuery(document).keydown(function (e) { |
||||||
|
switch (e.keyCode) { |
||||||
|
// SPACE / ENTER |
||||||
|
case 13: |
||||||
|
case 32: |
||||||
|
sendKey('DPAD_CENTER'); |
||||||
|
break; |
||||||
|
// W |
||||||
|
case 87: |
||||||
|
sendKey('DPAD_UP'); |
||||||
|
break; |
||||||
|
// D |
||||||
|
case 68: |
||||||
|
sendKey('DPAD_RIGHT'); |
||||||
|
break; |
||||||
|
// S |
||||||
|
case 83: |
||||||
|
sendKey('DPAD_LEFT'); |
||||||
|
break; |
||||||
|
// A |
||||||
|
case 65: |
||||||
|
sendKey('DPAD_LEFT'); |
||||||
|
break; |
||||||
|
// UP |
||||||
|
case 38: |
||||||
|
sendKey('VOLUME_UP'); |
||||||
|
break; |
||||||
|
// DOWN |
||||||
|
case 40: |
||||||
|
sendKey('VOLUME_DOWN'); |
||||||
|
break; |
||||||
|
// H |
||||||
|
case 72: |
||||||
|
sendKey('HOME'); |
||||||
|
break; |
||||||
|
// B |
||||||
|
case 72: |
||||||
|
sendKey('BACK'); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
</script> |
||||||
|
</body> |
||||||
|
</html> |
Loading…
Reference in new issue