mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-02-16 10:31:07 +00:00
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.
This commit is contained in:
committed by
Cameron Gutman
parent
a519723d44
commit
62bedb1609
@@ -67,8 +67,9 @@
|
||||
</activity>
|
||||
<!-- Small hack to support launcher shortcuts without relaunching over and over again when the back button is pressed -->
|
||||
<activity
|
||||
android:name=".AppViewShortcutTrampoline"
|
||||
android:name=".ShortcutTrampoline"
|
||||
android:noHistory="true"
|
||||
android:exported="true"
|
||||
android:resizeableActivity="true"
|
||||
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection">
|
||||
<meta-data
|
||||
|
||||
@@ -26,6 +26,9 @@ import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.view.ContextMenu;
|
||||
@@ -36,6 +39,7 @@ import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||
@@ -56,7 +60,9 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
private final static int START_OR_RESUME_ID = 1;
|
||||
private final static int QUIT_ID = 2;
|
||||
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 UUID_EXTRA = "UUID";
|
||||
@@ -331,10 +337,15 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
menu.add(Menu.NONE, QUIT_ID, 2, getResources().getString(R.string.applist_menu_quit));
|
||||
}
|
||||
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, VIEW_DETAILS_ID, 3, getResources().getString(R.string.applist_menu_details));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
menu.add(Menu.NONE, CREATE_SHORTCUT_ID, 4, getResources().getString(R.string.applist_menu_scut));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -346,7 +357,7 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
|
||||
final AppObject app = (AppObject) appGridAdapter.getItem(info.position);
|
||||
switch (item.getItemId()) {
|
||||
case START_WTIH_QUIT:
|
||||
case START_WITH_QUIT:
|
||||
// Display a confirmation dialog first
|
||||
UiHelper.displayQuitConfirmationDialog(this, new Runnable() {
|
||||
@Override
|
||||
@@ -386,6 +397,19 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
case CANCEL_ID:
|
||||
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:
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -113,6 +113,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
private final static int DELETE_ID = 5;
|
||||
private final static int RESUME_ID = 6;
|
||||
private final static int QUIT_ID = 7;
|
||||
private final static int VIEW_DETAILS_ID = 8;
|
||||
|
||||
private void initializeViews() {
|
||||
setContentView(R.layout.activity_pc_view);
|
||||
@@ -333,6 +334,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
// 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, VIEW_DETAILS_ID, 5, getResources().getString(R.string.pcview_menu_details));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -603,6 +605,10 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
}, null);
|
||||
return true;
|
||||
|
||||
case VIEW_DETAILS_ID:
|
||||
Dialog.displayDialog(PcView.this, getResources().getString(R.string.title_details), computer.details.toString(), false);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
|
||||
263
app/src/main/java/com/limelight/ShortcutTrampoline.java
Normal file
263
app/src/main/java/com/limelight/ShortcutTrampoline.java
Normal file
@@ -0,0 +1,263 @@
|
||||
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 {
|
||||
UiHelper.displayQuitConfirmationDialog(ShortcutTrampoline.this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
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[]{}));
|
||||
}
|
||||
}, 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();
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,15 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Build;
|
||||
|
||||
import com.limelight.AppView;
|
||||
import com.limelight.AppViewShortcutTrampoline;
|
||||
import com.limelight.ShortcutTrampoline;
|
||||
import com.limelight.R;
|
||||
import com.limelight.nvstream.http.ComputerDetails;
|
||||
import com.limelight.nvstream.http.NvApp;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
@@ -80,8 +82,7 @@ public class ShortcutHelper {
|
||||
|
||||
public void reportShortcutUsed(String id) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
ShortcutInfo sinfo = getInfoForId(id);
|
||||
if (sinfo != null) {
|
||||
if (getInfoForId(id) != null) {
|
||||
sm.reportShortcutUsed(id);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +90,7 @@ public class ShortcutHelper {
|
||||
|
||||
public void createAppViewShortcut(String id, String computerName, String computerUuid, boolean forceAdd) {
|
||||
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.UUID_EXTRA, computerUuid);
|
||||
i.setAction(Intent.ACTION_DEFAULT);
|
||||
@@ -127,10 +128,42 @@ public class ShortcutHelper {
|
||||
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) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
ShortcutInfo sinfo = getInfoForId(id);
|
||||
if (sinfo != null) {
|
||||
if (getInfoForId(id) != null) {
|
||||
sm.disableShortcuts(Collections.singletonList(id), reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
<!-- Shortcut strings -->
|
||||
<string name="scut_deleted_pc">PC deleted</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 -->
|
||||
<string name="help_loading_title">Help Viewer</string>
|
||||
@@ -17,6 +20,7 @@
|
||||
<string name="pcview_menu_unpair_pc">Unpair</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_details">View Details</string>
|
||||
|
||||
<!-- Pair messages -->
|
||||
<string name="pairing">Pairing…</string>
|
||||
@@ -55,6 +59,7 @@
|
||||
<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="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 -->
|
||||
<string name="conn_establishing_title">Establishing Connection</string>
|
||||
@@ -76,6 +81,7 @@
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
<string name="lost_connection">Lost connection to PC</string>
|
||||
<string name="title_details">Details</string>
|
||||
<string name="help">Help</string>
|
||||
|
||||
<!-- AppList activity -->
|
||||
@@ -85,6 +91,8 @@
|
||||
<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_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_msg">Refreshing apps…</string>
|
||||
<string name="applist_refresh_error_title">Error</string>
|
||||
@@ -93,6 +101,7 @@
|
||||
<string name="applist_quit_success">Successfully 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_details_id">App ID:</string>
|
||||
|
||||
<!-- Add computer manually activity -->
|
||||
<string name="title_add_pc">Add PC Manually</string>
|
||||
|
||||
Reference in New Issue
Block a user