Compare commits

..
23 Commits
Author SHA1 Message Date
Cameron Gutman 7dea322bbd Update build tools to 28.0.3 2018-09-29 15:37:31 -07:00
Cameron Gutman 349ecb16ab Increment version code 2018-09-29 15:36:21 -07:00
Cameron Gutman a3867735c1 Update to AGP 3.2 2018-09-29 15:31:13 -07:00
Cameron Gutman 5b087e9f70 Update common-c with split encode change 2018-09-22 20:22:59 -07:00
Cameron Gutman eed18223eb Version 5.9.2 2018-09-18 20:36:53 -07:00
Cameron Gutman 30d4d2a918 Update moonlight-common 2018-09-18 20:27:08 -07:00
Cameron Gutman 30f666c70e Update AGP to 3.2 rc3 2018-09-18 20:23:25 -07:00
Cameron Gutman 209fead0e8 Only add the create shortcut option if the box art is present to avoid crashing 2018-09-18 20:22:16 -07:00
Cameron Gutman 5c6889bf6d Version 5.9.1 2018-08-12 00:45:19 -07:00
Cameron Gutman 7d24900756 Update build tools to 28.0.2 2018-08-12 00:44:09 -07:00
Cameron Gutman 79a75b9d19 Update common with audio fix and game launch fix 2018-08-12 00:40:56 -07:00
Cameron Gutman 29b64992bd Enable stale and no-response bots to reduce inactive issues 2018-08-12 00:20:03 -07:00
Cameron Gutman c9b14540f2 Remove reference to old Moonlight Java project 2018-08-10 22:29:59 -07:00
Cameron Gutman 546843a26c Fix crash on quit confirmation prompt 2018-07-28 00:13:20 -07:00
Cameron Gutman d03d260535 Add status bar and navigation bar color on L+ 2018-07-27 23:48:20 -07:00
Cameron Gutman 6946e3c7a2 Just use the PC name as the app list title 2018-07-27 23:42:57 -07:00
Cameron Gutman b79d328961 Version 5.9 2018-07-16 18:46:01 -07:00
Cameron Gutman c313797d93 Make OSC reconfigure button non-focusable so it doesn't eat hardware enter/space presses. Fixes #611 2018-07-16 18:40:19 -07:00
Cameron Gutman c8cb8e1346 Update build tools to 28.0.1 2018-07-16 18:25:33 -07:00
Cameron Gutman 6a9f8da14e Update common to reduce syscall overhead 2018-07-16 18:21:48 -07:00
Cameron Gutman ff9260a0fd Update AGP to 3.2-beta4 2018-07-16 18:16:35 -07:00
zacklmoore 62bedb1609 Pinned Game Shortcuts (Android Oreo) (#603)
* Initial changes to add game shortcuts.

* Initial working cut.

* Cleanup and converting strings to resource strings.

* Additional cleanup.

* Removed a blank line

* Changes based on review feedback.

* Forgot to save some changes before commiting...

* Standardized dialogs and tried to fix the dialogs auto-closing when the PCView is already opened.
2018-07-06 21:53:19 -07:00
Cameron Gutman a519723d44 Monkey-proof Moonlight 2018-06-20 01:26:59 -07:00
24 changed files with 394 additions and 202 deletions

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
# ProBot No Response (https://probot.github.io/apps/no-response/)
daysUntilClose: 7
responseRequiredLabel: 'need more info'
closeComment: >
This issue has been automatically closed because there was no response to a
request for more information from the issue opener. Please leave a comment or
open a new issue if you have additional information related to this issue.
+14
View File
@@ -0,0 +1,14 @@
# ProBot Stale (https://probot.github.io/apps/stale/)
daysUntilStale: 90
daysUntilClose: 7
exemptLabels:
- accepted
- bug
- enhancement
- meta
staleLabel: stale
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs.
closeComment: false
+1 -3
View File
@@ -1,4 +1,4 @@
# Moonlight # Moonlight Android
[Moonlight](http://moonlight-stream.com) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield. [Moonlight](http://moonlight-stream.com) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield.
We reverse engineered the Shield streaming software and created a version that can be run on any Android device. We reverse engineered the Shield streaming software and created a version that can be run on any Android device.
@@ -6,8 +6,6 @@ We reverse engineered the Shield streaming software and created a version that c
Moonlight will allow you to stream your full collection of games from your Windows PC to your Android device, Moonlight will allow you to stream your full collection of games from your Windows PC to your Android device,
whether in your own home or over the internet. whether in your own home or over the internet.
[Moonlight-pc](https://github.com/moonlight-stream/moonlight-pc) is also currently in development for Windows, OS X and Linux. Versions for [iOS](https://github.com/moonlight-stream/moonlight-ios) and [Windows and Windows Phone](https://github.com/moonlight-stream/moonlight-windows) are also in development.
Check our [wiki](https://github.com/moonlight-stream/moonlight-docs/wiki) for more detailed information or a troubleshooting guide. Check our [wiki](https://github.com/moonlight-stream/moonlight-docs/wiki) for more detailed information or a troubleshooting guide.
## Features ## Features
+3 -3
View File
@@ -1,15 +1,15 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
buildToolsVersion '28.0.0' buildToolsVersion '28.0.3'
compileSdkVersion 28 compileSdkVersion 28
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 28 targetSdkVersion 28
versionName "5.8.2" versionName "5.9.2"
versionCode = 167 versionCode = 171
} }
flavorDimensions "root" flavorDimensions "root"
+2 -1
View File
@@ -67,8 +67,9 @@
</activity> </activity>
<!-- Small hack to support launcher shortcuts without relaunching over and over again when the back button is pressed --> <!-- Small hack to support launcher shortcuts without relaunching over and over again when the back button is pressed -->
<activity <activity
android:name=".AppViewShortcutTrampoline" android:name=".ShortcutTrampoline"
android:noHistory="true" android:noHistory="true"
android:exported="true"
android:resizeableActivity="true" android:resizeableActivity="true"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"> android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection">
<meta-data <meta-data
+35 -6
View File
@@ -26,6 +26,10 @@ import android.app.Service;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.view.ContextMenu; import android.view.ContextMenu;
@@ -36,6 +40,7 @@ import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AbsListView; import android.widget.AbsListView;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.AdapterContextMenuInfo;
@@ -56,7 +61,9 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
private final static int START_OR_RESUME_ID = 1; private final static int START_OR_RESUME_ID = 1;
private final static int QUIT_ID = 2; private final static int QUIT_ID = 2;
private final static int CANCEL_ID = 3; private final static int CANCEL_ID = 3;
private final static int START_WTIH_QUIT = 4; private final static int START_WITH_QUIT = 4;
private final static int VIEW_DETAILS_ID = 5;
private final static int CREATE_SHORTCUT_ID = 6;
public final static String NAME_EXTRA = "Name"; public final static String NAME_EXTRA = "Name";
public final static String UUID_EXTRA = "UUID"; public final static String UUID_EXTRA = "UUID";
@@ -251,10 +258,9 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
String computerName = getIntent().getStringExtra(NAME_EXTRA); String computerName = getIntent().getStringExtra(NAME_EXTRA);
String labelText = getResources().getString(R.string.title_applist)+" "+computerName;
TextView label = findViewById(R.id.appListText); TextView label = findViewById(R.id.appListText);
setTitle(labelText); setTitle(computerName);
label.setText(labelText); label.setText(computerName);
// Add a launcher shortcut for this PC (forced, since this is user interaction) // Add a launcher shortcut for this PC (forced, since this is user interaction)
shortcutHelper.createAppViewShortcut(uuidString, computerName, uuidString, true); shortcutHelper.createAppViewShortcut(uuidString, computerName, uuidString, true);
@@ -331,10 +337,20 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
menu.add(Menu.NONE, QUIT_ID, 2, getResources().getString(R.string.applist_menu_quit)); menu.add(Menu.NONE, QUIT_ID, 2, getResources().getString(R.string.applist_menu_quit));
} }
else { else {
menu.add(Menu.NONE, START_WTIH_QUIT, 1, getResources().getString(R.string.applist_menu_quit_and_start)); menu.add(Menu.NONE, START_WITH_QUIT, 1, getResources().getString(R.string.applist_menu_quit_and_start));
menu.add(Menu.NONE, CANCEL_ID, 2, getResources().getString(R.string.applist_menu_cancel)); menu.add(Menu.NONE, CANCEL_ID, 2, getResources().getString(R.string.applist_menu_cancel));
} }
} }
menu.add(Menu.NONE, VIEW_DETAILS_ID, 3, getResources().getString(R.string.applist_menu_details));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Only add an option to create shortcut if box art is loaded
ImageView appImageView = info.targetView.findViewById(R.id.grid_image);
BitmapDrawable drawable = (BitmapDrawable)appImageView.getDrawable();
if (drawable != null && drawable.getBitmap() != null) {
menu.add(Menu.NONE, CREATE_SHORTCUT_ID, 4, getResources().getString(R.string.applist_menu_scut));
}
}
} }
@Override @Override
@@ -346,7 +362,7 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
final AppObject app = (AppObject) appGridAdapter.getItem(info.position); final AppObject app = (AppObject) appGridAdapter.getItem(info.position);
switch (item.getItemId()) { switch (item.getItemId()) {
case START_WTIH_QUIT: case START_WITH_QUIT:
// Display a confirmation dialog first // Display a confirmation dialog first
UiHelper.displayQuitConfirmationDialog(this, new Runnable() { UiHelper.displayQuitConfirmationDialog(this, new Runnable() {
@Override @Override
@@ -386,6 +402,19 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
case CANCEL_ID: case CANCEL_ID:
return true; return true;
case VIEW_DETAILS_ID:
Dialog.displayDialog(AppView.this, getResources().getString(R.string.title_details),
getResources().getString(R.string.applist_details_id) + " " + app.app.getAppId(), false);
return true;
case CREATE_SHORTCUT_ID:
ImageView appImageView = info.targetView.findViewById(R.id.grid_image);
Bitmap appBits = ((BitmapDrawable)appImageView.getDrawable()).getBitmap();
if (!shortcutHelper.createPinnedGameShortcut(uuidString + Integer.valueOf(app.app.getAppId()).toString(), appBits, computer, app.app)) {
Toast.makeText(AppView.this, getResources().getString(R.string.unable_to_pin_shortcut), Toast.LENGTH_LONG).show();
}
return true;
default: default:
return super.onContextItemSelected(item); return super.onContextItemSelected(item);
} }
@@ -1,171 +0,0 @@
package com.limelight;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import com.limelight.computers.ComputerManagerListener;
import com.limelight.computers.ComputerManagerService;
import com.limelight.nvstream.http.ComputerDetails;
import com.limelight.nvstream.http.NvApp;
import com.limelight.utils.Dialog;
import com.limelight.utils.ServerHelper;
import com.limelight.utils.SpinnerDialog;
import com.limelight.utils.UiHelper;
import java.util.ArrayList;
import java.util.UUID;
public class AppViewShortcutTrampoline extends Activity {
private String uuidString;
private ComputerDetails computer;
private SpinnerDialog blockingLoadSpinner;
public final static String UUID_EXTRA = "UUID";
private ComputerManagerService.ComputerManagerBinder managerBinder;
private final ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
final ComputerManagerService.ComputerManagerBinder localBinder =
((ComputerManagerService.ComputerManagerBinder)binder);
// Wait in a separate thread to avoid stalling the UI
new Thread() {
@Override
public void run() {
// Wait for the binder to be ready
localBinder.waitForReady();
// Now make the binder visible
managerBinder = localBinder;
// Get the computer object
computer = managerBinder.getComputer(UUID.fromString(uuidString));
// Force CMS to repoll this machine
managerBinder.invalidateStateForComputer(computer.uuid);
// Start polling
managerBinder.startPolling(new ComputerManagerListener() {
@Override
public void notifyComputerUpdated(final ComputerDetails details) {
// Don't care about other computers
if (!details.uuid.toString().equalsIgnoreCase(uuidString)) {
return;
}
if (details.state != ComputerDetails.State.UNKNOWN) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// Stop showing the spinner
if (blockingLoadSpinner != null) {
blockingLoadSpinner.dismiss();
blockingLoadSpinner = null;
}
// If the managerBinder was destroyed before this callback,
// just finish the activity.
if (managerBinder == null) {
finish();
return;
}
if (details.state == ComputerDetails.State.ONLINE) {
// Close this activity
finish();
// Create a new activity stack for this launch
ArrayList<Intent> intentStack = new ArrayList<>();
Intent i;
// Add the PC view at the back (and clear the task)
i = new Intent(AppViewShortcutTrampoline.this, PcView.class);
i.setAction(Intent.ACTION_MAIN);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
intentStack.add(i);
// Take this intent's data and create an intent to start the app view
i = new Intent(getIntent());
i.setClass(AppViewShortcutTrampoline.this, AppView.class);
intentStack.add(i);
// If a game is running, we'll make the stream the top level activity
if (details.runningGameId != 0) {
intentStack.add(ServerHelper.createStartIntent(AppViewShortcutTrampoline.this,
new NvApp("app", details.runningGameId, false), details, managerBinder));
}
// Now start the activities
startActivities(intentStack.toArray(new Intent[]{}));
}
else if (details.state == ComputerDetails.State.OFFLINE) {
// Computer offline - display an error dialog
Dialog.displayDialog(AppViewShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.error_pc_offline),
true);
}
// We don't want any more callbacks from now on, so go ahead
// and unbind from the service
if (managerBinder != null) {
managerBinder.stopPolling();
unbindService(serviceConnection);
managerBinder = null;
}
}
});
}
}
});
}
}.start();
}
public void onServiceDisconnected(ComponentName className) {
managerBinder = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UiHelper.notifyNewRootView(this);
uuidString = getIntent().getStringExtra(UUID_EXTRA);
// 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
protected void onPause() {
super.onPause();
if (blockingLoadSpinner != null) {
blockingLoadSpinner.dismiss();
blockingLoadSpinner = null;
}
Dialog.closeDialogs();
if (managerBinder != null) {
managerBinder.stopPolling();
unbindService(serviceConnection);
managerBinder = null;
}
finish();
}
}
@@ -28,6 +28,7 @@ import com.limelight.utils.ShortcutHelper;
import com.limelight.utils.UiHelper; import com.limelight.utils.UiHelper;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManager;
import android.app.Service; import android.app.Service;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
@@ -112,6 +113,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
private final static int DELETE_ID = 5; private final static int DELETE_ID = 5;
private final static int RESUME_ID = 6; private final static int RESUME_ID = 6;
private final static int QUIT_ID = 7; private final static int QUIT_ID = 7;
private final static int VIEW_DETAILS_ID = 8;
private void initializeViews() { private void initializeViews() {
setContentView(R.layout.activity_pc_view); setContentView(R.layout.activity_pc_view);
@@ -332,6 +334,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
// it with delete which actually work // it with delete which actually work
menu.add(Menu.NONE, DELETE_ID, 4, getResources().getString(R.string.pcview_menu_delete_pc)); menu.add(Menu.NONE, DELETE_ID, 4, getResources().getString(R.string.pcview_menu_delete_pc));
} }
menu.add(Menu.NONE, VIEW_DETAILS_ID, 5, getResources().getString(R.string.pcview_menu_details));
} }
@Override @Override
@@ -560,6 +563,10 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
return true; return true;
case DELETE_ID: case DELETE_ID:
if (ActivityManager.isUserAMonkey()) {
LimeLog.info("Ignoring delete PC request from monkey");
return true;
}
if (managerBinder == null) { if (managerBinder == null) {
Toast.makeText(PcView.this, getResources().getString(R.string.error_manager_not_running), Toast.LENGTH_LONG).show(); Toast.makeText(PcView.this, getResources().getString(R.string.error_manager_not_running), Toast.LENGTH_LONG).show();
return true; return true;
@@ -598,6 +605,10 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
}, null); }, null);
return true; return true;
case VIEW_DETAILS_ID:
Dialog.displayDialog(PcView.this, getResources().getString(R.string.title_details), computer.details.toString(), false);
return true;
default: default:
return super.onContextItemSelected(item); return super.onContextItemSelected(item);
} }
@@ -0,0 +1,267 @@
package com.limelight;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import com.limelight.computers.ComputerManagerListener;
import com.limelight.computers.ComputerManagerService;
import com.limelight.nvstream.http.ComputerDetails;
import com.limelight.nvstream.http.NvApp;
import com.limelight.nvstream.http.PairingManager;
import com.limelight.utils.Dialog;
import com.limelight.utils.ServerHelper;
import com.limelight.utils.SpinnerDialog;
import com.limelight.utils.UiHelper;
import java.util.ArrayList;
import java.util.UUID;
public class ShortcutTrampoline extends Activity {
private String uuidString;
private String appIdString;
private ArrayList<Intent> intentStack = new ArrayList<>();
private ComputerDetails computer;
private SpinnerDialog blockingLoadSpinner;
public final static String APP_ID_EXTRA = "AppId";
private ComputerManagerService.ComputerManagerBinder managerBinder;
private final ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
final ComputerManagerService.ComputerManagerBinder localBinder =
((ComputerManagerService.ComputerManagerBinder)binder);
// Wait in a separate thread to avoid stalling the UI
new Thread() {
@Override
public void run() {
// Wait for the binder to be ready
localBinder.waitForReady();
// Now make the binder visible
managerBinder = localBinder;
// Get the computer object
computer = managerBinder.getComputer(UUID.fromString(uuidString));
if (computer == null) {
Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.scut_pc_not_found),
true);
if (blockingLoadSpinner != null) {
blockingLoadSpinner.dismiss();
blockingLoadSpinner = null;
}
if (managerBinder != null) {
unbindService(serviceConnection);
managerBinder = null;
}
return;
}
// Force CMS to repoll this machine
managerBinder.invalidateStateForComputer(computer.uuid);
// Start polling
managerBinder.startPolling(new ComputerManagerListener() {
@Override
public void notifyComputerUpdated(final ComputerDetails details) {
// Don't care about other computers
if (!details.uuid.toString().equalsIgnoreCase(uuidString)) {
return;
}
if (details.state != ComputerDetails.State.UNKNOWN) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// Stop showing the spinner
if (blockingLoadSpinner != null) {
blockingLoadSpinner.dismiss();
blockingLoadSpinner = null;
}
// If the managerBinder was destroyed before this callback,
// just finish the activity.
if (managerBinder == null) {
finish();
return;
}
if (details.state == ComputerDetails.State.ONLINE && details.pairState == PairingManager.PairState.PAIRED) {
// Launch game if provided app ID, otherwise launch app view
if (appIdString != null && appIdString.length() > 0) {
if (details.runningGameId == 0 || details.runningGameId == Integer.parseInt(appIdString)) {
intentStack.add(ServerHelper.createStartIntent(ShortcutTrampoline.this,
new NvApp("app", Integer.parseInt(appIdString), false), details, managerBinder));
// Close this activity
finish();
// Now start the activities
startActivities(intentStack.toArray(new Intent[]{}));
} else {
// Create the start intent immediately, so we can safely unbind the managerBinder
// below before we return.
final Intent startIntent = ServerHelper.createStartIntent(ShortcutTrampoline.this,
new NvApp("app", Integer.parseInt(appIdString), false), details, managerBinder);
UiHelper.displayQuitConfirmationDialog(ShortcutTrampoline.this, new Runnable() {
@Override
public void run() {
intentStack.add(startIntent);
// Close this activity
finish();
// Now start the activities
startActivities(intentStack.toArray(new Intent[]{}));
}
}, new Runnable() {
@Override
public void run() {
// Close this activity
finish();
}
});
}
} else {
// Close this activity
finish();
// Add the PC view at the back (and clear the task)
Intent i;
i = new Intent(ShortcutTrampoline.this, PcView.class);
i.setAction(Intent.ACTION_MAIN);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
intentStack.add(i);
// Take this intent's data and create an intent to start the app view
i = new Intent(getIntent());
i.setClass(ShortcutTrampoline.this, AppView.class);
intentStack.add(i);
// If a game is running, we'll make the stream the top level activity
if (details.runningGameId != 0) {
intentStack.add(ServerHelper.createStartIntent(ShortcutTrampoline.this,
new NvApp("app", details.runningGameId, false), details, managerBinder));
}
// Now start the activities
startActivities(intentStack.toArray(new Intent[]{}));
}
}
else if (details.state == ComputerDetails.State.OFFLINE) {
// Computer offline - display an error dialog
Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.error_pc_offline),
true);
} else if (details.pairState != PairingManager.PairState.PAIRED) {
// Computer not paired - display an error dialog
Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.scut_not_paired),
true);
}
// We don't want any more callbacks from now on, so go ahead
// and unbind from the service
if (managerBinder != null) {
managerBinder.stopPolling();
unbindService(serviceConnection);
managerBinder = null;
}
}
});
}
}
});
}
}.start();
}
public void onServiceDisconnected(ComponentName className) {
managerBinder = null;
}
};
protected boolean validateInput() {
// Validate UUID
try {
UUID.fromString(uuidString);
} catch (IllegalArgumentException ex) {
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)
if (appIdString != null && !appIdString.isEmpty()) {
try {
Integer.parseInt(appIdString);
} catch (NumberFormatException ex) {
Dialog.displayDialog(ShortcutTrampoline.this,
getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.scut_invalid_app_id),
true);
return false;
}
}
return true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UiHelper.notifyNewRootView(this);
uuidString = getIntent().getStringExtra(AppView.UUID_EXTRA);
appIdString = getIntent().getStringExtra(APP_ID_EXTRA);
if (validateInput()) {
// 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
protected void onStop() {
super.onStop();
if (blockingLoadSpinner != null) {
blockingLoadSpinner.dismiss();
blockingLoadSpinner = null;
}
Dialog.closeDialogs();
if (managerBinder != null) {
managerBinder.stopPolling();
unbindService(serviceConnection);
managerBinder = null;
}
finish();
}
}
@@ -60,6 +60,7 @@ public class VirtualController {
buttonConfigure = new Button(context); buttonConfigure = new Button(context);
buttonConfigure.setAlpha(0.25f); buttonConfigure.setAlpha(0.25f);
buttonConfigure.setFocusable(false);
buttonConfigure.setBackgroundResource(R.drawable.ic_settings); buttonConfigure.setBackgroundResource(R.drawable.ic_settings);
buttonConfigure.setOnClickListener(new View.OnClickListener() { buttonConfigure.setOnClickListener(new View.OnClickListener() {
@Override @Override
@@ -5,13 +5,15 @@ import android.content.Context;
import android.content.Intent; 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.drawable.Icon; import android.graphics.drawable.Icon;
import android.os.Build; import android.os.Build;
import com.limelight.AppView; import com.limelight.AppView;
import com.limelight.AppViewShortcutTrampoline; 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 java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
@@ -80,8 +82,7 @@ public class ShortcutHelper {
public void reportShortcutUsed(String id) { public void reportShortcutUsed(String id) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
ShortcutInfo sinfo = getInfoForId(id); if (getInfoForId(id) != null) {
if (sinfo != null) {
sm.reportShortcutUsed(id); sm.reportShortcutUsed(id);
} }
} }
@@ -89,7 +90,7 @@ public class ShortcutHelper {
public void createAppViewShortcut(String id, String computerName, String computerUuid, boolean forceAdd) { public void createAppViewShortcut(String id, String computerName, String computerUuid, boolean forceAdd) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
Intent i = new Intent(context, AppViewShortcutTrampoline.class); Intent i = new Intent(context, ShortcutTrampoline.class);
i.putExtra(AppView.NAME_EXTRA, computerName); i.putExtra(AppView.NAME_EXTRA, computerName);
i.putExtra(AppView.UUID_EXTRA, computerUuid); i.putExtra(AppView.UUID_EXTRA, computerUuid);
i.setAction(Intent.ACTION_DEFAULT); i.setAction(Intent.ACTION_DEFAULT);
@@ -127,10 +128,42 @@ public class ShortcutHelper {
createAppViewShortcut(id, details.name, details.uuid.toString(), forceAdd); createAppViewShortcut(id, details.name, details.uuid.toString(), forceAdd);
} }
@TargetApi(Build.VERSION_CODES.O)
public boolean createPinnedGameShortcut(String id, Bitmap iconBits, String computerName, String computerUuid, String appName, String appId) {
if (sm.isRequestPinShortcutSupported()) {
Icon appIcon;
Intent i = new Intent(context, ShortcutTrampoline.class);
i.putExtra(AppView.NAME_EXTRA, computerName);
i.putExtra(AppView.UUID_EXTRA, computerUuid);
i.putExtra(ShortcutTrampoline.APP_ID_EXTRA, appId);
i.setAction(Intent.ACTION_DEFAULT);
if (iconBits != null) {
appIcon = Icon.createWithAdaptiveBitmap(iconBits);
} else {
appIcon = Icon.createWithResource(context, R.mipmap.ic_pc_scut);
}
ShortcutInfo sInfo = new ShortcutInfo.Builder(context, id)
.setIntent(i)
.setShortLabel(appName + " (" + computerName + ")")
.setIcon(appIcon)
.build();
return sm.requestPinShortcut(sInfo, null);
} else {
return false;
}
}
public boolean createPinnedGameShortcut(String id, Bitmap iconBits, ComputerDetails cDetails, NvApp app) {
return createPinnedGameShortcut(id, iconBits, cDetails.name, cDetails.uuid.toString(), app.getAppName(), Integer.valueOf(app.getAppId()).toString());
}
public void disableShortcut(String id, CharSequence reason) { public void disableShortcut(String id, CharSequence reason) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
ShortcutInfo sinfo = getInfoForId(id); if (getInfoForId(id) != null) {
if (sinfo != null) {
sm.disableShortcuts(Collections.singletonList(id), reason); sm.disableShortcuts(Collections.singletonList(id), reason);
} }
} }
-1
View File
@@ -61,7 +61,6 @@
<string name="lost_connection">Conexión perdida</string> <string name="lost_connection">Conexión perdida</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">Aplicaciones en</string>
<string name="applist_menu_resume">Reanudar sesión</string> <string name="applist_menu_resume">Reanudar sesión</string>
<string name="applist_menu_quit">Cerrar sesión</string> <string name="applist_menu_quit">Cerrar sesión</string>
<string name="applist_menu_quit_and_start">Cerrar juego actual e iniciar</string> <string name="applist_menu_quit_and_start">Cerrar juego actual e iniciar</string>
-1
View File
@@ -71,7 +71,6 @@
<string name="help">Aide</string> <string name="help">Aide</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">Applications sur</string>
<string name="applist_connect_msg">Connexion au PC…</string> <string name="applist_connect_msg">Connexion au PC…</string>
<string name="applist_menu_resume">Reprise de la session</string> <string name="applist_menu_resume">Reprise de la session</string>
<string name="applist_menu_quit">Quitter la session</string> <string name="applist_menu_quit">Quitter la session</string>
-1
View File
@@ -76,7 +76,6 @@
<string name="help">Assistenza</string> <string name="help">Assistenza</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">Applicazioni su</string>
<string name="applist_connect_msg">Connessione al PC in corso…</string> <string name="applist_connect_msg">Connessione al PC in corso…</string>
<string name="applist_menu_resume">Riprendi sessione</string> <string name="applist_menu_resume">Riprendi sessione</string>
<string name="applist_menu_quit">Chiudi sessione</string> <string name="applist_menu_quit">Chiudi sessione</string>
-1
View File
@@ -57,7 +57,6 @@
<string name="lost_connection">コンピュータとの接続が失われました</string> <string name="lost_connection">コンピュータとの接続が失われました</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">ゲーム</string>
<string name="applist_menu_resume">セッションを続ける</string> <string name="applist_menu_resume">セッションを続ける</string>
<string name="applist_menu_quit">セッションを終了する</string> <string name="applist_menu_quit">セッションを終了する</string>
<string name="applist_menu_quit_and_start">現在のゲームを終了して新しいゲームを始める</string> <string name="applist_menu_quit_and_start">現在のゲームを終了して新しいゲームを始める</string>
-1
View File
@@ -71,7 +71,6 @@
<string name="help">도움말</string> <string name="help">도움말</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">앱 사용 가능</string>
<string name="applist_connect_msg">PC에 연결중…</string> <string name="applist_connect_msg">PC에 연결중…</string>
<string name="applist_menu_resume">세션 계속</string> <string name="applist_menu_resume">세션 계속</string>
<string name="applist_menu_quit">세션 종료</string> <string name="applist_menu_quit">세션 종료</string>
-1
View File
@@ -61,7 +61,6 @@
<string name="lost_connection">Verbinding met PC verloren</string> <string name="lost_connection">Verbinding met PC verloren</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">Apps op</string>
<string name="applist_menu_resume">Hervat Sessie</string> <string name="applist_menu_resume">Hervat Sessie</string>
<string name="applist_menu_quit">Stop Sessie</string> <string name="applist_menu_quit">Stop Sessie</string>
<string name="applist_menu_quit_and_start">Stop Huidige Spel en Start</string> <string name="applist_menu_quit_and_start">Stop Huidige Spel en Start</string>
-1
View File
@@ -62,7 +62,6 @@
<string name="lost_connection">Потеряно соединение с PC</string> <string name="lost_connection">Потеряно соединение с PC</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">Приложения на</string>
<string name="applist_menu_resume">Возобновить сессию</string> <string name="applist_menu_resume">Возобновить сессию</string>
<string name="applist_menu_quit">Выйти из сессии</string> <string name="applist_menu_quit">Выйти из сессии</string>
<string name="applist_menu_quit_and_start">Выйти из текущей игры и запустить</string> <string name="applist_menu_quit_and_start">Выйти из текущей игры и запустить</string>
+2
View File
@@ -7,6 +7,8 @@
--> -->
<style name="AppBaseTheme" parent="android:Theme.Material"> <style name="AppBaseTheme" parent="android:Theme.Material">
<!-- API 21 theme customizations can go here. --> <!-- API 21 theme customizations can go here. -->
<item name="android:statusBarColor">#212121</item>
<item name="android:navigationBarColor">#212121</item>
</style> </style>
</resources> </resources>
@@ -71,7 +71,6 @@
<string name="help">帮助</string> <string name="help">帮助</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">Apps on</string>
<string name="applist_connect_msg"> 连接到电脑中…… </string> <string name="applist_connect_msg"> 连接到电脑中…… </string>
<string name="applist_menu_resume"> 恢复串流 </string> <string name="applist_menu_resume"> 恢复串流 </string>
<string name="applist_menu_quit"> 退出串流 </string> <string name="applist_menu_quit"> 退出串流 </string>
@@ -71,7 +71,6 @@
<string name="help">幫助</string> <string name="help">幫助</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">Apps on</string>
<string name="applist_connect_msg"> 連接到電腦中…… </string> <string name="applist_connect_msg"> 連接到電腦中…… </string>
<string name="applist_menu_resume"> 恢復串流 </string> <string name="applist_menu_resume"> 恢復串流 </string>
<string name="applist_menu_quit"> 退出串流 </string> <string name="applist_menu_quit"> 退出串流 </string>
+9 -1
View File
@@ -6,6 +6,9 @@
<!-- Shortcut strings --> <!-- Shortcut strings -->
<string name="scut_deleted_pc">PC deleted</string> <string name="scut_deleted_pc">PC deleted</string>
<string name="scut_not_paired">PC not paired</string> <string name="scut_not_paired">PC not paired</string>
<string name="scut_pc_not_found">PC not found</string>
<string name="scut_invalid_uuid">Provided PC is not valid</string>
<string name="scut_invalid_app_id">Provided App is not valid</string>
<!-- Help strings --> <!-- Help strings -->
<string name="help_loading_title">Help Viewer</string> <string name="help_loading_title">Help Viewer</string>
@@ -17,6 +20,7 @@
<string name="pcview_menu_unpair_pc">Unpair</string> <string name="pcview_menu_unpair_pc">Unpair</string>
<string name="pcview_menu_send_wol">Send Wake-On-LAN request</string> <string name="pcview_menu_send_wol">Send Wake-On-LAN request</string>
<string name="pcview_menu_delete_pc">Delete PC</string> <string name="pcview_menu_delete_pc">Delete PC</string>
<string name="pcview_menu_details">View Details</string>
<!-- Pair messages --> <!-- Pair messages -->
<string name="pairing">Pairing…</string> <string name="pairing">Pairing…</string>
@@ -55,6 +59,7 @@
<string name="title_decoding_reset">Video Settings Reset</string> <string name="title_decoding_reset">Video Settings Reset</string>
<string name="message_decoding_reset">Your device\'s video decoder continues to crash at your selected streaming settings. Your streaming settings have been reset to default.</string> <string name="message_decoding_reset">Your device\'s video decoder continues to crash at your selected streaming settings. Your streaming settings have been reset to default.</string>
<string name="error_usb_prohibited">USB access is prohibited by your device administrator. Check your Knox or MDM settings.</string> <string name="error_usb_prohibited">USB access is prohibited by your device administrator. Check your Knox or MDM settings.</string>
<string name="unable_to_pin_shortcut">Your current launcher does not allow for creating pinned shortcuts.</string>
<!-- Start application messages --> <!-- Start application messages -->
<string name="conn_establishing_title">Establishing Connection</string> <string name="conn_establishing_title">Establishing Connection</string>
@@ -76,15 +81,17 @@
<string name="yes">Yes</string> <string name="yes">Yes</string>
<string name="no">No</string> <string name="no">No</string>
<string name="lost_connection">Lost connection to PC</string> <string name="lost_connection">Lost connection to PC</string>
<string name="title_details">Details</string>
<string name="help">Help</string> <string name="help">Help</string>
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">Apps on</string>
<string name="applist_connect_msg">Connecting to PC…</string> <string name="applist_connect_msg">Connecting to PC…</string>
<string name="applist_menu_resume">Resume Session</string> <string name="applist_menu_resume">Resume Session</string>
<string name="applist_menu_quit">Quit Session</string> <string name="applist_menu_quit">Quit Session</string>
<string name="applist_menu_quit_and_start">Quit Current Game and Start</string> <string name="applist_menu_quit_and_start">Quit Current Game and Start</string>
<string name="applist_menu_cancel">Cancel</string> <string name="applist_menu_cancel">Cancel</string>
<string name="applist_menu_details">View Details</string>
<string name="applist_menu_scut">Create Shortcut</string>
<string name="applist_refresh_title">App List</string> <string name="applist_refresh_title">App List</string>
<string name="applist_refresh_msg">Refreshing apps…</string> <string name="applist_refresh_msg">Refreshing apps…</string>
<string name="applist_refresh_error_title">Error</string> <string name="applist_refresh_error_title">Error</string>
@@ -93,6 +100,7 @@
<string name="applist_quit_success">Successfully quit</string> <string name="applist_quit_success">Successfully quit</string>
<string name="applist_quit_fail">Failed to quit</string> <string name="applist_quit_fail">Failed to quit</string>
<string name="applist_quit_confirmation">Are you sure you want to quit the running app? All unsaved data will be lost.</string> <string name="applist_quit_confirmation">Are you sure you want to quit the running app? All unsaved data will be lost.</string>
<string name="applist_details_id">App ID:</string>
<!-- Add computer manually activity --> <!-- Add computer manually activity -->
<string name="title_add_pc">Add PC Manually</string> <string name="title_add_pc">Add PC Manually</string>
+1 -1
View File
@@ -5,7 +5,7 @@ buildscript {
google() google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.2.0-alpha18' classpath 'com.android.tools.build:gradle:3.2.0'
} }
} }