mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-18 10:32:43 +00:00
Create the PC channel on pairing and add each app to it upon launch
This commit is contained in:
parent
d9c0830198
commit
fd53122cb3
@ -19,7 +19,6 @@ import com.limelight.utils.Dialog;
|
||||
import com.limelight.utils.ServerHelper;
|
||||
import com.limelight.utils.ShortcutHelper;
|
||||
import com.limelight.utils.SpinnerDialog;
|
||||
import com.limelight.utils.TvChannelHelper;
|
||||
import com.limelight.utils.UiHelper;
|
||||
|
||||
import android.app.Activity;
|
||||
@ -51,7 +50,6 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
private AppGridAdapter appGridAdapter;
|
||||
private String uuidString;
|
||||
private ShortcutHelper shortcutHelper;
|
||||
private TvChannelHelper tvChannelHelper;
|
||||
|
||||
private ComputerDetails computer;
|
||||
private ComputerManagerService.ApplistPoller poller;
|
||||
@ -67,10 +65,10 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
private final static int START_WITH_QUIT = 4;
|
||||
private final static int VIEW_DETAILS_ID = 5;
|
||||
private final static int CREATE_SHORTCUT_ID = 6;
|
||||
private final static int ADD_TO_TV_CHANNEL = 7;
|
||||
|
||||
public final static String NAME_EXTRA = "Name";
|
||||
public final static String UUID_EXTRA = "UUID";
|
||||
public final static String NEW_PAIR_EXTRA = "NewPair";
|
||||
|
||||
private ComputerManagerService.ComputerManagerBinder managerBinder;
|
||||
private final ServiceConnection serviceConnection = new ServiceConnection() {
|
||||
@ -187,9 +185,6 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
shortcutHelper.disableShortcut(details.uuid,
|
||||
getResources().getString(R.string.scut_not_paired));
|
||||
|
||||
//Delete channel of PC for now
|
||||
tvChannelHelper.deleteChannel(details.uuid);
|
||||
|
||||
// Display a toast to the user and quit the activity
|
||||
Toast.makeText(AppView.this, getResources().getText(R.string.scut_not_paired), Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
@ -258,7 +253,6 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
inForeground = true;
|
||||
|
||||
shortcutHelper = new ShortcutHelper(this);
|
||||
tvChannelHelper = new TvChannelHelper(this);
|
||||
|
||||
UiHelper.setLocale(this);
|
||||
|
||||
@ -275,9 +269,8 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
label.setText(computerName);
|
||||
|
||||
// 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, getIntent().getBooleanExtra(NEW_PAIR_EXTRA, false));
|
||||
shortcutHelper.reportShortcutUsed(uuidString);
|
||||
tvChannelHelper.createTvChannel(uuidString, computerName);
|
||||
|
||||
// Bind to the computer manager service
|
||||
bindService(new Intent(this, ComputerManagerService.class), serviceConnection,
|
||||
@ -356,9 +349,7 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
}
|
||||
menu.add(Menu.NONE, VIEW_DETAILS_ID, 3, getResources().getString(R.string.applist_menu_details));
|
||||
|
||||
if (tvChannelHelper.isSupport()) {
|
||||
menu.add(Menu.NONE, ADD_TO_TV_CHANNEL, 4, getResources().getString(R.string.applist_menu_tv_channel));
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Only add an option to create shortcut if box art is loaded
|
||||
// and when we're in grid-mode (not list-mode).
|
||||
ImageView appImageView = info.targetView.findViewById(R.id.grid_image);
|
||||
@ -434,10 +425,6 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
}
|
||||
return true;
|
||||
|
||||
case ADD_TO_TV_CHANNEL:
|
||||
tvChannelHelper.addGameToChannel(computer, app.app);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
|
@ -268,10 +268,12 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
return;
|
||||
}
|
||||
|
||||
// Add a launcher shortcut for this PC (forced, since this is user interaction)
|
||||
// Report this shortcut being used
|
||||
shortcutHelper = new ShortcutHelper(this);
|
||||
shortcutHelper.createAppViewShortcut(uuid, pcName, uuid, true);
|
||||
shortcutHelper.reportShortcutUsed(uuid);
|
||||
if (appName != null) {
|
||||
shortcutHelper.reportGameLaunched(uuid, pcName, ""+appId, appName);
|
||||
}
|
||||
|
||||
// Initialize the MediaCodec helper before creating the decoder
|
||||
GlPreferences glPrefs = GlPreferences.readPreferences(this);
|
||||
@ -412,7 +414,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
StreamConfiguration config = new StreamConfiguration.Builder()
|
||||
.setResolution(prefConfig.width, prefConfig.height)
|
||||
.setRefreshRate(prefConfig.fps)
|
||||
.setApp(new NvApp(appName, appId, willStreamHdr))
|
||||
.setApp(new NvApp(appName != null ? appName : "app", appId, willStreamHdr))
|
||||
.setBitrate(prefConfig.bitrate)
|
||||
.setEnableSops(prefConfig.enableSops)
|
||||
.enableLocalAudioPlayback(prefConfig.playHostAudio)
|
||||
|
@ -25,7 +25,6 @@ import com.limelight.utils.Dialog;
|
||||
import com.limelight.utils.HelpLauncher;
|
||||
import com.limelight.utils.ServerHelper;
|
||||
import com.limelight.utils.ShortcutHelper;
|
||||
import com.limelight.utils.TvChannelHelper;
|
||||
import com.limelight.utils.UiHelper;
|
||||
|
||||
import android.app.Activity;
|
||||
@ -63,7 +62,6 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
private RelativeLayout noPcFoundLayout;
|
||||
private PcGridAdapter pcGridAdapter;
|
||||
private ShortcutHelper shortcutHelper;
|
||||
private TvChannelHelper tvChannelHelper;
|
||||
private ComputerManagerService.ComputerManagerBinder managerBinder;
|
||||
private boolean freezeUpdates, runningPolling, inForeground, completeOnCreateCalled;
|
||||
private final ServiceConnection serviceConnection = new ServiceConnection() {
|
||||
@ -217,7 +215,6 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
completeOnCreateCalled = true;
|
||||
|
||||
shortcutHelper = new ShortcutHelper(this);
|
||||
tvChannelHelper = new TvChannelHelper(this);
|
||||
|
||||
UiHelper.setLocale(this);
|
||||
|
||||
@ -443,7 +440,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
|
||||
if (toastSuccess) {
|
||||
// Open the app list after a successful pairing attempt
|
||||
doAppList(computer);
|
||||
doAppList(computer, true);
|
||||
}
|
||||
else {
|
||||
// Start polling again if we're still in the foreground
|
||||
@ -542,7 +539,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void doAppList(ComputerDetails computer) {
|
||||
private void doAppList(ComputerDetails computer, boolean newlyPaired) {
|
||||
if (computer.state == ComputerDetails.State.OFFLINE) {
|
||||
Toast.makeText(PcView.this, getResources().getString(R.string.error_pc_offline), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
@ -555,6 +552,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
Intent i = new Intent(this, AppView.class);
|
||||
i.putExtra(AppView.NAME_EXTRA, computer.name);
|
||||
i.putExtra(AppView.UUID_EXTRA, computer.uuid);
|
||||
i.putExtra(AppView.NEW_PAIR_EXTRA, newlyPaired);
|
||||
startActivity(i);
|
||||
}
|
||||
|
||||
@ -594,7 +592,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
return true;
|
||||
|
||||
case APP_LIST_ID:
|
||||
doAppList(computer.details);
|
||||
doAppList(computer.details, false);
|
||||
return true;
|
||||
|
||||
case RESUME_ID:
|
||||
@ -640,9 +638,6 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
shortcutHelper.disableShortcut(details.uuid,
|
||||
getResources().getString(R.string.scut_deleted_pc));
|
||||
|
||||
//Delete channel of PC
|
||||
tvChannelHelper.deleteChannel(details.uuid);
|
||||
|
||||
pcGridAdapter.removeComputer(computer);
|
||||
pcGridAdapter.notifyDataSetChanged();
|
||||
|
||||
@ -671,7 +666,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
|
||||
// Add a launcher shortcut for this PC
|
||||
if (details.pairState == PairState.PAIRED) {
|
||||
shortcutHelper.createAppViewShortcut(details.uuid, details, false);
|
||||
shortcutHelper.createAppViewShortcutForOnlineHost(details);
|
||||
}
|
||||
|
||||
if (existingEntry != null) {
|
||||
@ -713,7 +708,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
// Pair an unpaired machine by default
|
||||
doPair(computer.details);
|
||||
} else {
|
||||
doAppList(computer.details);
|
||||
doAppList(computer.details, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -104,7 +104,7 @@ public class ShortcutTrampoline extends Activity {
|
||||
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));
|
||||
new NvApp(null, Integer.parseInt(appIdString), false), details, managerBinder));
|
||||
|
||||
// Close this activity
|
||||
finish();
|
||||
@ -115,7 +115,7 @@ public class ShortcutTrampoline extends Activity {
|
||||
// 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);
|
||||
new NvApp(null, Integer.parseInt(appIdString), false), details, managerBinder);
|
||||
|
||||
UiHelper.displayQuitConfirmationDialog(ShortcutTrampoline.this, new Runnable() {
|
||||
@Override
|
||||
@ -155,7 +155,7 @@ public class ShortcutTrampoline extends Activity {
|
||||
// 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));
|
||||
new NvApp(null, details.runningGameId, false), details, managerBinder));
|
||||
}
|
||||
|
||||
// Now start the activities
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.limelight.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
@ -22,9 +22,10 @@ import java.util.List;
|
||||
public class ShortcutHelper {
|
||||
|
||||
private final ShortcutManager sm;
|
||||
private final Context context;
|
||||
private final Activity context;
|
||||
private final TvChannelHelper tvChannelHelper;
|
||||
|
||||
public ShortcutHelper(Context context) {
|
||||
public ShortcutHelper(Activity context) {
|
||||
this.context = context;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
sm = context.getSystemService(ShortcutManager.class);
|
||||
@ -32,6 +33,7 @@ public class ShortcutHelper {
|
||||
else {
|
||||
sm = null;
|
||||
}
|
||||
this.tvChannelHelper = new TvChannelHelper(context);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
@ -80,15 +82,20 @@ public class ShortcutHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void reportShortcutUsed(String id) {
|
||||
public void reportShortcutUsed(String computerUuid) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
if (getInfoForId(id) != null) {
|
||||
sm.reportShortcutUsed(id);
|
||||
if (getInfoForId(computerUuid) != null) {
|
||||
sm.reportShortcutUsed(computerUuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void createAppViewShortcut(String id, String computerName, String computerUuid, boolean forceAdd) {
|
||||
public void reportGameLaunched(String computerUuid, String computerName, String appId, String appName) {
|
||||
tvChannelHelper.createTvChannel(computerUuid, computerName);
|
||||
tvChannelHelper.addGameToChannel(computerUuid, computerName, appId, appName);
|
||||
}
|
||||
|
||||
public void createAppViewShortcut(String id, String computerName, String computerUuid, boolean forceAdd, boolean newlyPaired) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
Intent i = new Intent(context, ShortcutTrampoline.class);
|
||||
i.putExtra(AppView.NAME_EXTRA, computerName);
|
||||
@ -122,10 +129,16 @@ public class ShortcutHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newlyPaired) {
|
||||
// Avoid hammering the channel API for each computer poll because it will throttle us
|
||||
tvChannelHelper.createTvChannel(computerUuid, computerName);
|
||||
tvChannelHelper.requestChannelOnHomeScreen(computerUuid);
|
||||
}
|
||||
}
|
||||
|
||||
public void createAppViewShortcut(String id, ComputerDetails details, boolean forceAdd) {
|
||||
createAppViewShortcut(id, details.name, details.uuid, forceAdd);
|
||||
public void createAppViewShortcutForOnlineHost(ComputerDetails details) {
|
||||
createAppViewShortcut(details.uuid, details.name, details.uuid, false, false);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
@ -161,10 +174,11 @@ public class ShortcutHelper {
|
||||
return createPinnedGameShortcut(id, iconBits, cDetails.name, cDetails.uuid, app.getAppName(), Integer.valueOf(app.getAppId()).toString());
|
||||
}
|
||||
|
||||
public void disableShortcut(String id, CharSequence reason) {
|
||||
public void disableShortcut(String uuid, CharSequence reason) {
|
||||
tvChannelHelper.deleteChannel(uuid);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
if (getInfoForId(id) != null) {
|
||||
sm.disableShortcuts(Collections.singletonList(id), reason);
|
||||
if (getInfoForId(uuid) != null) {
|
||||
sm.disableShortcuts(Collections.singletonList(uuid), reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package com.limelight.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.UiModeManager;
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.graphics.Bitmap;
|
||||
@ -21,99 +21,91 @@ import com.limelight.LimeLog;
|
||||
import com.limelight.PosterContentProvider;
|
||||
import com.limelight.R;
|
||||
import com.limelight.ShortcutTrampoline;
|
||||
import com.limelight.nvstream.http.ComputerDetails;
|
||||
import com.limelight.nvstream.http.NvApp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public class TvChannelHelper {
|
||||
|
||||
private static final int ASPECT_RATIO_MOVIE_POSTER = 5;
|
||||
private static final int TYPE_GAME = 12;
|
||||
public static final String[] CHANNEL_PROJECTION = {TvContract.Channels._ID, TvContract.Channels.COLUMN_INTERNAL_PROVIDER_ID};
|
||||
public static final int INTERNAL_PROVIDER_ID_INDEX = 1;
|
||||
public static final int ID_INDEX = 0;
|
||||
private Context context;
|
||||
private static final int INTERNAL_PROVIDER_ID_INDEX = 1;
|
||||
private static final int ID_INDEX = 0;
|
||||
private Activity context;
|
||||
|
||||
public TvChannelHelper(Context context) {
|
||||
public TvChannelHelper(Activity context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public boolean createTvChannel(String computerUuid, String computerName) {
|
||||
if (!isSupport()) {
|
||||
return false;
|
||||
void requestChannelOnHomeScreen(String computerUuid) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (!isAndroidTV()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Long channelId = getChannelId(computerUuid);
|
||||
if (channelId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent = new Intent(TvContract.ACTION_REQUEST_CHANNEL_BROWSABLE);
|
||||
intent.putExtra(TvContract.EXTRA_CHANNEL_ID, getChannelId(computerUuid));
|
||||
try {
|
||||
context.startActivityForResult(intent, 0);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
}
|
||||
}
|
||||
|
||||
Intent i = new Intent(context, ShortcutTrampoline.class);
|
||||
i.putExtra(AppView.NAME_EXTRA, computerName);
|
||||
i.putExtra(AppView.UUID_EXTRA, computerUuid);
|
||||
i.setAction(Intent.ACTION_DEFAULT);
|
||||
ChannelBuilder builder = new ChannelBuilder()
|
||||
.setType(TvContract.Channels.TYPE_PREVIEW)
|
||||
.setDisplayName(computerName)
|
||||
.setInternalProviderId(computerUuid)
|
||||
.setAppLinkIntent(i);
|
||||
|
||||
Long channelId = getChannelId(computerUuid);
|
||||
|
||||
|
||||
if (channelId != null) {
|
||||
context.getContentResolver().update(TvContract.buildChannelUri(channelId),
|
||||
builder.toContentValues(), null, null);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Uri channelUri = context.getContentResolver().insert(
|
||||
TvContract.Channels.CONTENT_URI, builder.toContentValues());
|
||||
|
||||
|
||||
if (channelUri != null) {
|
||||
long id = ContentUris.parseId(channelUri);
|
||||
updateChannelIcon(id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateChannelIcon(long id) {
|
||||
Bitmap bitmap = drawableToBitmap(context.getResources().getDrawable(R.drawable.ic_channel));
|
||||
void createTvChannel(String computerUuid, String computerName) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (!isAndroidTV()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Intent i = new Intent(context, ShortcutTrampoline.class);
|
||||
i.putExtra(AppView.NAME_EXTRA, computerName);
|
||||
i.putExtra(AppView.UUID_EXTRA, computerUuid);
|
||||
i.setAction(Intent.ACTION_DEFAULT);
|
||||
ChannelBuilder builder = new ChannelBuilder()
|
||||
.setType(TvContract.Channels.TYPE_PREVIEW)
|
||||
.setDisplayName(computerName)
|
||||
.setInternalProviderId(computerUuid)
|
||||
.setAppLinkIntent(i);
|
||||
|
||||
Long channelId = getChannelId(computerUuid);
|
||||
if (channelId != null) {
|
||||
context.getContentResolver().update(TvContract.buildChannelUri(channelId),
|
||||
builder.toContentValues(), null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
Uri channelUri = context.getContentResolver().insert(
|
||||
TvContract.Channels.CONTENT_URI, builder.toContentValues());
|
||||
if (channelUri != null) {
|
||||
long id = ContentUris.parseId(channelUri);
|
||||
updateChannelIcon(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
private void updateChannelIcon(long channelId) {
|
||||
Bitmap logo = drawableToBitmap(context.getResources().getDrawable(R.drawable.ic_channel));
|
||||
try {
|
||||
storeChannelLogo(id, bitmap);
|
||||
Uri localUri = TvContract.buildChannelLogoUri(channelId);
|
||||
try (OutputStream outputStream = context.getContentResolver().openOutputStream(localUri)) {
|
||||
logo.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
|
||||
outputStream.flush();
|
||||
} catch (SQLiteException | IOException e) {
|
||||
LimeLog.warning("Failed to store the logo to the system content provider.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
bitmap.recycle();
|
||||
logo.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stores the given channel logo {@link Bitmap} in the system content provider and associate
|
||||
* it with the given channel ID.
|
||||
*
|
||||
* @param channelId the ID of the target channel with which the given logo should be associated
|
||||
* @param logo the logo image to be stored
|
||||
* @return {@code true} if successfully stored the logo in the system content provider,
|
||||
* otherwise {@code false}.
|
||||
*/
|
||||
private boolean storeChannelLogo(long channelId,
|
||||
Bitmap logo) {
|
||||
if (!isSupport()) {
|
||||
return false;
|
||||
}
|
||||
boolean result = false;
|
||||
Uri localUri = TvContract.buildChannelLogoUri(channelId);
|
||||
try (OutputStream outputStream = context.getContentResolver().openOutputStream(localUri)) {
|
||||
result = logo.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
|
||||
outputStream.flush();
|
||||
} catch (SQLiteException | IOException e) {
|
||||
LimeLog.warning("Failed to store the logo to the system content provider.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Bitmap drawableToBitmap(Drawable drawable) {
|
||||
int width = context.getResources().getDimensionPixelSize(R.dimen.tv_channel_logo_width);
|
||||
int height = context.getResources().getDimensionPixelSize(R.dimen.tv_channel_logo_width);
|
||||
@ -125,59 +117,62 @@ public class TvChannelHelper {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
void addGameToChannel(String computerUuid, String computerName, String appId, String appName) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (!isAndroidTV()) {
|
||||
return;
|
||||
}
|
||||
|
||||
public boolean addGameToChannel(String computerUuid, String computerName, String appId, String appName) {
|
||||
if (!isSupport()) {
|
||||
return false;
|
||||
PreviewProgramBuilder builder = new PreviewProgramBuilder();
|
||||
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);
|
||||
|
||||
Uri resourceURI = PosterContentProvider.createBoxArtUri(computerUuid, appId);
|
||||
|
||||
Long channelId = getChannelId(computerUuid);
|
||||
if (channelId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
builder.setChannelId(channelId)
|
||||
.setType(TYPE_GAME)
|
||||
.setTitle(appName)
|
||||
.setPosterArtAspectRatio(ASPECT_RATIO_MOVIE_POSTER)
|
||||
.setPosterArtUri(resourceURI)
|
||||
.setIntent(i)
|
||||
.setInternalProviderId(appId);
|
||||
|
||||
context.getContentResolver().insert(TvContract.PreviewPrograms.CONTENT_URI,
|
||||
builder.toContentValues());
|
||||
|
||||
TvContract.requestChannelBrowsable(context, channelId);
|
||||
}
|
||||
|
||||
PreviewProgramBuilder builder = new PreviewProgramBuilder();
|
||||
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);
|
||||
|
||||
Uri resourceURI = PosterContentProvider.createBoxArtUri(computerUuid, appId);
|
||||
|
||||
Long channelId = getChannelId(computerUuid);
|
||||
|
||||
|
||||
if (channelId == null) {
|
||||
return false;
|
||||
}
|
||||
builder.setChannelId(channelId)
|
||||
.setType(TYPE_GAME)
|
||||
.setTitle(appName)
|
||||
.setPosterArtAspectRatio(ASPECT_RATIO_MOVIE_POSTER)
|
||||
.setPosterArtUri(resourceURI)
|
||||
.setIntent(i)
|
||||
.setInternalProviderId(appId);
|
||||
Uri programUri = context.getContentResolver().insert(TvContract.PreviewPrograms.CONTENT_URI,
|
||||
builder.toContentValues());
|
||||
|
||||
|
||||
TvContract.requestChannelBrowsable(context, channelId);
|
||||
return programUri != null;
|
||||
}
|
||||
|
||||
public boolean deleteChannel(String computerUuid) {
|
||||
if (!isSupport()) {
|
||||
return false;
|
||||
}
|
||||
Long channelId = getChannelId(computerUuid);
|
||||
if (channelId == null) {
|
||||
return false;
|
||||
}
|
||||
Uri uri = TvContract.buildChannelUri(channelId);
|
||||
return context.getContentResolver().delete(uri, null, null) > 0;
|
||||
void deleteChannel(String computerUuid) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (!isAndroidTV()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Long channelId = getChannelId(computerUuid);
|
||||
if (channelId == null) {
|
||||
return;
|
||||
}
|
||||
Uri uri = TvContract.buildChannelUri(channelId);
|
||||
context.getContentResolver().delete(uri, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
private Long getChannelId(String computerUuid) {
|
||||
Uri uri = TvContract.Channels.CONTENT_URI;
|
||||
final String[] CHANNEL_PROJECTION = {TvContract.Channels._ID, TvContract.Channels.COLUMN_INTERNAL_PROVIDER_ID};
|
||||
|
||||
Cursor cursor = context.getContentResolver().query(uri,
|
||||
CHANNEL_PROJECTION,
|
||||
null,
|
||||
@ -202,11 +197,6 @@ public class TvChannelHelper {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addGameToChannel(ComputerDetails computer, NvApp app) {
|
||||
addGameToChannel(computer.uuid, computer.name, String.valueOf(app.getAppId()), app.getAppName());
|
||||
}
|
||||
|
||||
private static <T> String toValueString(T value) {
|
||||
return value == null ? null : value.toString();
|
||||
}
|
||||
@ -215,15 +205,12 @@ public class TvChannelHelper {
|
||||
return intent == null ? null : intent.toUri(Intent.URI_INTENT_SCHEME);
|
||||
}
|
||||
|
||||
public boolean isSupport() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UiModeManager uiModeManager = (UiModeManager) context.getSystemService(Context.UI_MODE_SERVICE);
|
||||
return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION;
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public boolean isAndroidTV() {
|
||||
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
private static class PreviewProgramBuilder {
|
||||
|
||||
private ContentValues mValues = new ContentValues();
|
||||
@ -275,6 +262,7 @@ public class TvChannelHelper {
|
||||
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
private static class ChannelBuilder {
|
||||
|
||||
private ContentValues mValues = new ContentValues();
|
||||
|
Loading…
x
Reference in New Issue
Block a user