feat(activity): allow PC Name and AppName for ShortcutTrampoline (#1387)

This commit is contained in:
ReenigneArcher 2024-07-27 17:23:23 -04:00 committed by GitHub
parent 85ed72802f
commit b7b6adaff7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 155 additions and 30 deletions

View File

@ -8,19 +8,26 @@ import android.content.ServiceConnection;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import com.limelight.computers.ComputerDatabaseManager;
import com.limelight.computers.ComputerManagerListener; import com.limelight.computers.ComputerManagerListener;
import com.limelight.computers.ComputerManagerService; import com.limelight.computers.ComputerManagerService;
import com.limelight.nvstream.http.ComputerDetails; import com.limelight.nvstream.http.ComputerDetails;
import com.limelight.nvstream.http.NvApp; import com.limelight.nvstream.http.NvApp;
import com.limelight.nvstream.http.NvHTTP;
import com.limelight.nvstream.http.PairingManager; import com.limelight.nvstream.http.PairingManager;
import com.limelight.nvstream.wol.WakeOnLanSender; import com.limelight.nvstream.wol.WakeOnLanSender;
import com.limelight.utils.CacheHelper;
import com.limelight.utils.Dialog; import com.limelight.utils.Dialog;
import com.limelight.utils.ServerHelper; import com.limelight.utils.ServerHelper;
import com.limelight.utils.SpinnerDialog; import com.limelight.utils.SpinnerDialog;
import com.limelight.utils.UiHelper; import com.limelight.utils.UiHelper;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
public class ShortcutTrampoline extends Activity { public class ShortcutTrampoline extends Activity {
@ -33,6 +40,7 @@ public class ShortcutTrampoline extends Activity {
private SpinnerDialog blockingLoadSpinner; private SpinnerDialog blockingLoadSpinner;
private ComputerManagerService.ComputerManagerBinder managerBinder; private ComputerManagerService.ComputerManagerBinder managerBinder;
private final ServiceConnection serviceConnection = new ServiceConnection() { private final ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) { public void onServiceConnected(ComponentName className, IBinder binder) {
final ComputerManagerService.ComputerManagerBinder localBinder = final ComputerManagerService.ComputerManagerBinder localBinder =
@ -214,9 +222,9 @@ public class ShortcutTrampoline extends Activity {
} }
}; };
protected boolean validateInput(String uuidString, String appIdString) { protected boolean validateInput(String uuidString, String appIdString, String nameString) {
// Validate UUID // Validate PC UUID/Name
if (uuidString == null) { if (uuidString == null && nameString == null) {
Dialog.displayDialog(ShortcutTrampoline.this, Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title), getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.scut_invalid_uuid), getResources().getString(R.string.scut_invalid_uuid),
@ -224,14 +232,25 @@ public class ShortcutTrampoline extends Activity {
return false; return false;
} }
try { if (uuidString != null && !uuidString.isEmpty()) {
UUID.fromString(uuidString); try {
} catch (IllegalArgumentException ex) { UUID.fromString(uuidString);
Dialog.displayDialog(ShortcutTrampoline.this, } catch (IllegalArgumentException ex) {
getResources().getString(R.string.conn_error_title), Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.scut_invalid_uuid), getResources().getString(R.string.conn_error_title),
true); getResources().getString(R.string.scut_invalid_uuid),
return false; true);
return false;
}
} else {
// UUID is null, so fallback to Name
if (nameString == null || nameString.isEmpty()) {
Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.scut_invalid_uuid),
true);
return false;
}
} }
// Validate App ID (if provided) // Validate App ID (if provided)
@ -255,24 +274,93 @@ public class ShortcutTrampoline extends Activity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
UiHelper.notifyNewRootView(this); UiHelper.notifyNewRootView(this);
ComputerDatabaseManager dbManager = new ComputerDatabaseManager(this);
ComputerDetails _computer = null;
String appIdString = getIntent().getStringExtra(Game.EXTRA_APP_ID); // PC arguments, both are optional, but at least one must be provided
uuidString = getIntent().getStringExtra(AppView.UUID_EXTRA); uuidString = getIntent().getStringExtra(AppView.UUID_EXTRA);
String nameString = getIntent().getStringExtra(AppView.NAME_EXTRA);
if (validateInput(uuidString, appIdString)) { // App arguments, both are optional, but one must be provided in order to start an app
if (appIdString != null && !appIdString.isEmpty()) { String appIdString = getIntent().getStringExtra(Game.EXTRA_APP_ID);
app = new NvApp(getIntent().getStringExtra(Game.EXTRA_APP_NAME), String appNameString = getIntent().getStringExtra(Game.EXTRA_APP_NAME);
Integer.parseInt(appIdString),
getIntent().getBooleanExtra(Game.EXTRA_APP_HDR, false)); if (!validateInput(uuidString, appIdString, nameString)) {
// Invalid input, so just return
return;
}
if (uuidString == null || uuidString.isEmpty()) {
// Use nameString to find the corresponding UUID
_computer = dbManager.getComputerByName(nameString);
if (_computer == null) {
Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.scut_pc_not_found),
true);
return;
} }
// Bind to the computer manager service uuidString = _computer.uuid;
bindService(new Intent(this, ComputerManagerService.class), serviceConnection,
Service.BIND_AUTO_CREATE);
blockingLoadSpinner = SpinnerDialog.displayDialog(this, getResources().getString(R.string.conn_establishing_title), // Set the AppView UUID intent, since it wasn't provided
getResources().getString(R.string.applist_connect_msg), true); setIntent(new Intent(getIntent()).putExtra(AppView.UUID_EXTRA, uuidString));
} }
if (appIdString != null && !appIdString.isEmpty()) {
app = new NvApp(getIntent().getStringExtra(Game.EXTRA_APP_NAME),
Integer.parseInt(appIdString),
getIntent().getBooleanExtra(Game.EXTRA_APP_HDR, false));
}
else if (appNameString != null && !appNameString.isEmpty()) {
// Use appNameString to find the corresponding AppId
try {
int appId = -1;
String rawAppList = CacheHelper.readInputStreamToString(CacheHelper.openCacheFileForInput(getCacheDir(), "applist", uuidString));
if (rawAppList.isEmpty()) {
Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.scut_invalid_app_id),
true);
return;
}
List<NvApp> applist = NvHTTP.getAppListByReader(new StringReader(rawAppList));
for (NvApp _app : applist) {
if (_app.getAppName().equals(appNameString)) {
appId = _app.getAppId();
break;
}
}
if (appId < 0) {
Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.scut_invalid_app_id),
true);
return;
}
setIntent(new Intent(getIntent()).putExtra(Game.EXTRA_APP_ID, appId));
app = new NvApp(
appNameString,
appId,
getIntent().getBooleanExtra(Game.EXTRA_APP_HDR, false));
} catch (IOException | XmlPullParserException e) {
Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.scut_invalid_app_id),
true);
return;
}
}
// Bind to the computer manager service
bindService(new Intent(this, ComputerManagerService.class), serviceConnection,
Service.BIND_AUTO_CREATE);
blockingLoadSpinner = SpinnerDialog.displayDialog(this, getResources().getString(R.string.conn_establishing_title),
getResources().getString(R.string.applist_connect_msg), true);
} }
@Override @Override

View File

@ -190,6 +190,35 @@ public class ComputerDatabaseManager {
} }
} }
/**
* Get a computer by name
* NOTE: It is perfectly valid for multiple computers to have the same name,
* this function will only return the first one it finds.
* Consider using getComputerByUUID instead.
* @param name The name of the computer
* @see ComputerDatabaseManager#getComputerByUUID(String) for alternative.
* @return The computer details, or null if no computer with that name exists
*/
public ComputerDetails getComputerByName(String name) {
try (final Cursor c = computerDb.query(
COMPUTER_TABLE_NAME, null, COMPUTER_NAME_COLUMN_NAME+"=?",
new String[]{ name }, null, null, null)
) {
if (!c.moveToFirst()) {
// No matching computer
return null;
}
return getComputerFromCursor(c);
}
}
/**
* Get a computer by UUID
* @param uuid The UUID of the computer
* @see ComputerDatabaseManager#getComputerByName(String) for alternative.
* @return The computer details, or null if no computer with that UUID exists
*/
public ComputerDetails getComputerByUUID(String uuid) { public ComputerDetails getComputerByUUID(String uuid) {
try (final Cursor c = computerDb.query( try (final Cursor c = computerDb.query(
COMPUTER_TABLE_NAME, null, COMPUTER_UUID_COLUMN_NAME+"=?", COMPUTER_TABLE_NAME, null, COMPUTER_UUID_COLUMN_NAME+"=?",

View File

@ -586,6 +586,12 @@ public class NvHTTP {
} }
} }
/**
* Get an app by ID
* @param appId The ID of the app
* @see #getAppByName(String) for alternative.
* @return app details, or null if no app with that ID exists
*/
public NvApp getAppById(int appId) throws IOException, XmlPullParserException { public NvApp getAppById(int appId) throws IOException, XmlPullParserException {
LinkedList<NvApp> appList = getAppList(); LinkedList<NvApp> appList = getAppList();
for (NvApp appFromList : appList) { for (NvApp appFromList : appList) {
@ -596,10 +602,15 @@ public class NvHTTP {
return null; return null;
} }
/* NOTE: Only use this function if you know what you're doing. /**
* It's totally valid to have two apps named the same thing, * Get an app by name
* or even nothing at all! Look apps up by ID if at all possible * NOTE: It is perfectly valid for multiple apps to have the same name,
* using the above function */ * this function will only return the first one it finds.
* Consider using getAppById instead.
* @param appName The name of the app
* @see #getAppById(int) for alternative.
* @return app details, or null if no app with that name exists
*/
public NvApp getAppByName(String appName) throws IOException, XmlPullParserException { public NvApp getAppByName(String appName) throws IOException, XmlPullParserException {
LinkedList<NvApp> appList = getAppList(); LinkedList<NvApp> appList = getAppList();
for (NvApp appFromList : appList) { for (NvApp appFromList : appList) {

View File

@ -2,15 +2,12 @@ package com.limelight.utils;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager; import android.content.pm.ShortcutManager;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.os.Build; import android.os.Build;
import com.limelight.AppView;
import com.limelight.ShortcutTrampoline;
import com.limelight.R; import com.limelight.R;
import com.limelight.nvstream.http.ComputerDetails; import com.limelight.nvstream.http.ComputerDetails;
import com.limelight.nvstream.http.NvApp; import com.limelight.nvstream.http.NvApp;