Resolve merge conflicts

This commit is contained in:
Ansa89
2014-11-12 09:41:12 +01:00
26 changed files with 750 additions and 389 deletions
+6
View File
@@ -101,12 +101,18 @@
</content> </content>
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" /> <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="okhttp-2.1.0-RC1" level="project" />
<orderEntry type="library" exported="" name="bcprov-jdk15on-1.51" level="project" /> <orderEntry type="library" exported="" name="bcprov-jdk15on-1.51" level="project" />
<orderEntry type="library" exported="" name="androidasync-1.3.7" level="project" />
<orderEntry type="library" exported="" name="jmdns-fixed" level="project" /> <orderEntry type="library" exported="" name="jmdns-fixed" level="project" />
<orderEntry type="library" exported="" name="jcodec-0.1.6-3" level="project" /> <orderEntry type="library" exported="" name="jcodec-0.1.6-3" level="project" />
<orderEntry type="library" exported="" name="bcpkix-jdk15on-1.51" level="project" /> <orderEntry type="library" exported="" name="bcpkix-jdk15on-1.51" level="project" />
<orderEntry type="library" exported="" name="tinyrtsp" level="project" /> <orderEntry type="library" exported="" name="tinyrtsp" level="project" />
<orderEntry type="library" exported="" name="limelight-common" level="project" /> <orderEntry type="library" exported="" name="limelight-common" level="project" />
<orderEntry type="library" exported="" name="support-v4-r6" level="project" />
<orderEntry type="library" exported="" name="gson-2.3" level="project" />
<orderEntry type="library" exported="" name="okio-1.0.1" level="project" />
<orderEntry type="library" exported="" name="ion-1.3.7" level="project" />
</component> </component>
</module> </module>
+6 -2
View File
@@ -11,8 +11,8 @@ android {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 21 targetSdkVersion 21
versionName "2.9" versionName "3.0-beta1.01"
versionCode = 38 versionCode = 41
} }
productFlavors { productFlavors {
@@ -65,6 +65,10 @@ dependencies {
compile group: 'org.jcodec', name: 'jcodec', version: '0.1.6-3' compile group: 'org.jcodec', name: 'jcodec', version: '0.1.6-3'
compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.51' compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.51'
compile group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.51' compile group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.51'
compile group: 'com.google.android', name: 'support-v4', version:'r6'
compile group: 'com.koushikdutta.ion', name: 'ion', version:'1.3.7'
compile group: 'com.squareup.okhttp', name: 'okhttp', version:'2.1.0-RC1'
compile group: 'com.squareup.okio', name:'okio', version:'1.0.1'
compile files('libs/jmdns-fixed.jar') compile files('libs/jmdns-fixed.jar')
compile files('libs/limelight-common.jar') compile files('libs/limelight-common.jar')
compile files('libs/tinyrtsp.jar') compile files('libs/tinyrtsp.jar')
Binary file not shown.
+32 -45
View File
@@ -4,15 +4,17 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import com.limelight.binding.PlatformBinding; import com.limelight.binding.PlatformBinding;
import com.limelight.grid.AppGridAdapter;
import com.limelight.nvstream.http.GfeHttpResponseException; import com.limelight.nvstream.http.GfeHttpResponseException;
import com.limelight.nvstream.http.NvApp; import com.limelight.nvstream.http.NvApp;
import com.limelight.nvstream.http.NvHTTP; import com.limelight.nvstream.http.NvHTTP;
import com.limelight.R;
import com.limelight.utils.Dialog; import com.limelight.utils.Dialog;
import com.limelight.utils.SpinnerDialog; import com.limelight.utils.SpinnerDialog;
import com.limelight.utils.UiHelper; import com.limelight.utils.UiHelper;
@@ -27,15 +29,14 @@ import android.view.View;
import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter; import android.widget.GridView;
import android.widget.ListView;
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;
public class AppView extends Activity { public class AppView extends Activity {
private ListView appList; private GridView appGrid;
private ArrayAdapter<AppObject> appListAdapter; private AppGridAdapter appGridAdapter;
private InetAddress ipAddress; private InetAddress ipAddress;
private String uniqueId; private String uniqueId;
private boolean remote; private boolean remote;
@@ -60,6 +61,7 @@ public class AppView extends Activity {
uniqueId = getIntent().getStringExtra(UNIQUEID_EXTRA); uniqueId = getIntent().getStringExtra(UNIQUEID_EXTRA);
remote = getIntent().getBooleanExtra(REMOTE_EXTRA, false); remote = getIntent().getBooleanExtra(REMOTE_EXTRA, false);
if (address == null || uniqueId == null) { if (address == null || uniqueId == null) {
finish();
return; return;
} }
@@ -71,20 +73,26 @@ public class AppView extends Activity {
try { try {
ipAddress = InetAddress.getByAddress(address); ipAddress = InetAddress.getByAddress(address);
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
e.printStackTrace();
finish();
return; return;
} }
// Setup the list view // Setup the list view
appList = (ListView)findViewById(R.id.pcListView); appGrid = (GridView)findViewById(R.id.appGridView);
appListAdapter = new ArrayAdapter<AppObject>(this, R.layout.simplerow, R.id.rowTextView); try {
appListAdapter.setNotifyOnChange(false); appGridAdapter = new AppGridAdapter(this, ipAddress, uniqueId);
appList.setAdapter(appListAdapter); } catch (Exception e) {
appList.setItemsCanFocus(true); e.printStackTrace();
appList.setOnItemClickListener(new OnItemClickListener() { finish();
return;
}
appGrid.setAdapter(appGridAdapter);
appGrid.setOnItemClickListener(new OnItemClickListener() {
@Override @Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
long id) { long id) {
AppObject app = appListAdapter.getItem(pos); AppObject app = (AppObject) appGridAdapter.getItem(pos);
if (app == null || app.app == null) { if (app == null || app.app == null) {
return; return;
} }
@@ -98,7 +106,7 @@ public class AppView extends Activity {
} }
} }
}); });
registerForContextMenu(appList); registerForContextMenu(appGrid);
} }
@Override @Override
@@ -118,8 +126,8 @@ public class AppView extends Activity {
private int getRunningAppId() { private int getRunningAppId() {
int runningAppId = -1; int runningAppId = -1;
for (int i = 0; i < appListAdapter.getCount(); i++) { for (int i = 0; i < appGridAdapter.getCount(); i++) {
AppObject app = appListAdapter.getItem(i); AppObject app = (AppObject) appGridAdapter.getItem(i);
if (app.app == null) { if (app.app == null) {
continue; continue;
} }
@@ -137,7 +145,7 @@ public class AppView extends Activity {
super.onCreateContextMenu(menu, v, menuInfo); super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
AppObject selectedApp = appListAdapter.getItem(info.position); AppObject selectedApp = (AppObject) appGridAdapter.getItem(info.position);
if (selectedApp == null || selectedApp.app == null) { if (selectedApp == null || selectedApp.app == null) {
return; return;
} }
@@ -162,9 +170,8 @@ public class AppView extends Activity {
@Override @Override
public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
AppObject app = appListAdapter.getItem(info.position); AppObject app = (AppObject) appGridAdapter.getItem(info.position);
switch (item.getItemId()) switch (item.getItemId()) {
{
case RESUME_ID: case RESUME_ID:
// Resume is the same as start for us // Resume is the same as start for us
doStart(app.app); doStart(app.app);
@@ -182,22 +189,9 @@ public class AppView extends Activity {
} }
} }
private static String generateString(NvApp app) {
StringBuilder str = new StringBuilder();
str.append(app.getAppName());
if (app.getIsRunning()) {
str.append(" - "+getResources().getString(R.string.applist_app_running));
}
return str.toString();
}
private void addListPlaceholder() {
appListAdapter.add(new AppObject(getResources().getString(R.string.applist_no_apps), null));
}
private void updateAppList() { private void updateAppList() {
final SpinnerDialog spinner = SpinnerDialog.displayDialog(this, getResources().getString(R.string.applist_refresh_title), final SpinnerDialog spinner = SpinnerDialog.displayDialog(this, getResources().getString(R.string.applist_refresh_title),
getResources().getString(R.string.applist_refresh_msg), true); getResources().getString(R.string.applist_refresh_title), true);
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
@@ -209,17 +203,12 @@ public class AppView extends Activity {
AppView.this.runOnUiThread(new Runnable() { AppView.this.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
appListAdapter.clear(); appGridAdapter.clear();
if (appList.isEmpty()) {
addListPlaceholder();
}
else {
for (NvApp app : appList) { for (NvApp app : appList) {
appListAdapter.add(new AppObject(generateString(app), app)); appGridAdapter.addApp(new AppObject(app));
}
} }
appListAdapter.notifyDataSetChanged(); appGridAdapter.notifyDataSetChanged();
} }
}); });
@@ -282,17 +271,15 @@ public class AppView extends Activity {
} }
public class AppObject { public class AppObject {
public String text;
public NvApp app; public NvApp app;
public AppObject(String text, NvApp app) { public AppObject(NvApp app) {
this.text = text;
this.app = app; this.app = app;
} }
@Override @Override
public String toString() { public String toString() {
return text; return app.getAppName();
} }
} }
} }
+2 -2
View File
@@ -678,8 +678,8 @@ public class Game extends Activity implements SurfaceHolder.Callback,
e.printStackTrace(); e.printStackTrace();
stopConnection(); stopConnection();
Dialog.displayDialog(this, getResources().getString(R.string.conn_fail_title), Dialog.displayDialog(this, getResources().getString(R.string.conn_terminated_title),
getResources().getString(R.string.conn_fail_msg), true); getResources().getString(R.string.conn_terminated_msg), true);
} }
} }
+44 -93
View File
@@ -9,6 +9,7 @@ import com.limelight.binding.PlatformBinding;
import com.limelight.binding.crypto.AndroidCryptoProvider; import com.limelight.binding.crypto.AndroidCryptoProvider;
import com.limelight.computers.ComputerManagerListener; import com.limelight.computers.ComputerManagerListener;
import com.limelight.computers.ComputerManagerService; import com.limelight.computers.ComputerManagerService;
import com.limelight.grid.PcGridAdapter;
import com.limelight.nvstream.http.ComputerDetails; import com.limelight.nvstream.http.ComputerDetails;
import com.limelight.nvstream.http.NvHTTP; import com.limelight.nvstream.http.NvHTTP;
import com.limelight.nvstream.http.PairingManager; import com.limelight.nvstream.http.PairingManager;
@@ -36,16 +37,18 @@ import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.ListView; import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.Toast; import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.AdapterContextMenuInfo;
public class PcView extends Activity { public class PcView extends Activity {
private Button settingsButton, addComputerButton; private ImageButton settingsButton, addComputerButton;
private ListView pcList; private RelativeLayout noPcFoundLayout;
private ArrayAdapter<ComputerObject> pcListAdapter; private GridView pcGrid;
private PcGridAdapter pcGridAdapter;
private ComputerManagerService.ComputerManagerBinder managerBinder; private ComputerManagerService.ComputerManagerBinder managerBinder;
private boolean freezeUpdates, runningPolling; private boolean freezeUpdates, runningPolling;
private ServiceConnection serviceConnection = new ServiceConnection() { private ServiceConnection serviceConnection = new ServiceConnection() {
@@ -99,20 +102,18 @@ public class PcView extends Activity {
PreferenceManager.setDefaultValues(this, R.xml.preferences, false); PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
// Setup the list view // Setup the list view
settingsButton = (Button)findViewById(R.id.settingsButton); settingsButton = (ImageButton)findViewById(R.id.settingsButton);
addComputerButton = (Button)findViewById(R.id.manuallyAddPc); addComputerButton = (ImageButton)findViewById(R.id.manuallyAddPc);
pcList = (ListView)findViewById(R.id.pcListView); pcGrid = (GridView)findViewById(R.id.pcGridView);
pcList.setAdapter(pcListAdapter); pcGrid.setAdapter(pcGridAdapter);
pcList.setItemsCanFocus(true); pcGrid.setOnItemClickListener(new OnItemClickListener() {
pcList.setOnItemClickListener(new OnItemClickListener() {
@Override @Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
long id) { long id) {
ComputerObject computer = pcListAdapter.getItem(pos); ComputerObject computer = (ComputerObject) pcGridAdapter.getItem(pos);
if (computer.details == null) { if (computer.details.reachability == ComputerDetails.Reachability.UNKNOWN) {
// Placeholder item; no context menu for it // Do nothing
return;
} }
else if (computer.details.reachability == ComputerDetails.Reachability.OFFLINE) { else if (computer.details.reachability == ComputerDetails.Reachability.OFFLINE) {
// Open the context menu if a PC is offline // Open the context menu if a PC is offline
@@ -127,7 +128,7 @@ public class PcView extends Activity {
} }
} }
}); });
registerForContextMenu(pcList); registerForContextMenu(pcGrid);
settingsButton.setOnClickListener(new OnClickListener() { settingsButton.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@@ -142,12 +143,14 @@ public class PcView extends Activity {
} }
}); });
if (pcListAdapter.isEmpty()) { noPcFoundLayout = (RelativeLayout) findViewById(R.id.no_pc_found_layout);
addListPlaceholder(); if (pcGridAdapter.getCount() == 0) {
noPcFoundLayout.setVisibility(View.VISIBLE);
} }
else { else {
pcListAdapter.notifyDataSetChanged(); noPcFoundLayout.setVisibility(View.INVISIBLE);
} }
pcGridAdapter.notifyDataSetChanged();
} }
@Override @Override
@@ -158,8 +161,7 @@ public class PcView extends Activity {
bindService(new Intent(PcView.this, ComputerManagerService.class), serviceConnection, bindService(new Intent(PcView.this, ComputerManagerService.class), serviceConnection,
Service.BIND_AUTO_CREATE); Service.BIND_AUTO_CREATE);
pcListAdapter = new ArrayAdapter<ComputerObject>(this, R.layout.simplerow, R.id.rowTextView); pcGridAdapter = new PcGridAdapter(this);
pcListAdapter.setNotifyOnChange(false);
initializeViews(); initializeViews();
} }
@@ -178,7 +180,7 @@ public class PcView extends Activity {
PcView.this.runOnUiThread(new Runnable() { PcView.this.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
updateListView(details); updateComputer(details);
} }
}); });
} }
@@ -244,8 +246,9 @@ public class PcView extends Activity {
super.onCreateContextMenu(menu, v, menuInfo); super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
ComputerObject computer = pcListAdapter.getItem(info.position); ComputerObject computer = (ComputerObject) pcGridAdapter.getItem(info.position);
if (computer == null || computer.details == null) { if (computer == null || computer.details == null ||
computer.details.reachability == ComputerDetails.Reachability.UNKNOWN) {
startComputerUpdates(); startComputerUpdates();
return; return;
} }
@@ -257,10 +260,8 @@ public class PcView extends Activity {
} }
else if (computer.details.pairState != PairState.PAIRED) { else if (computer.details.pairState != PairState.PAIRED) {
menu.add(Menu.NONE, PAIR_ID, 1, getResources().getString(R.string.pcview_menu_pair_pc)); menu.add(Menu.NONE, PAIR_ID, 1, getResources().getString(R.string.pcview_menu_pair_pc));
if (computer.details.reachability == ComputerDetails.Reachability.REMOTE) {
menu.add(Menu.NONE, DELETE_ID, 2, getResources().getString(R.string.pcview_menu_delete_pc)); menu.add(Menu.NONE, DELETE_ID, 2, getResources().getString(R.string.pcview_menu_delete_pc));
} }
}
else { else {
menu.add(Menu.NONE, APP_LIST_ID, 1, getResources().getString(R.string.pcview_menu_app_list)); menu.add(Menu.NONE, APP_LIST_ID, 1, getResources().getString(R.string.pcview_menu_app_list));
menu.add(Menu.NONE, UNPAIR_ID, 2, getResources().getString(R.string.pcview_menu_unpair_pc)); menu.add(Menu.NONE, UNPAIR_ID, 2, getResources().getString(R.string.pcview_menu_unpair_pc));
@@ -338,6 +339,7 @@ public class PcView extends Activity {
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
message = getResources().getString(R.string.error_404); message = getResources().getString(R.string.error_404);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
message = e.getMessage(); message = e.getMessage();
} }
@@ -479,7 +481,7 @@ public class PcView extends Activity {
@Override @Override
public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
ComputerObject computer = pcListAdapter.getItem(info.position); ComputerObject computer = (ComputerObject) pcGridAdapter.getItem(info.position);
switch (item.getItemId()) switch (item.getItemId())
{ {
case PAIR_ID: case PAIR_ID:
@@ -500,7 +502,7 @@ public class PcView extends Activity {
return true; return true;
} }
managerBinder.removeComputer(computer.details.name); managerBinder.removeComputer(computer.details.name);
removeListView(computer.details); removeComputer(computer.details);
return true; return true;
case APP_LIST_ID: case APP_LIST_ID:
@@ -512,68 +514,22 @@ public class PcView extends Activity {
} }
} }
private static String generateString(ComputerDetails details) { private void removeComputer(ComputerDetails details) {
StringBuilder str = new StringBuilder(); for (int i = 0; i < pcGridAdapter.getCount(); i++) {
str.append(details.name).append(" - "); ComputerObject computer = (ComputerObject) pcGridAdapter.getItem(i);
if (details.state == ComputerDetails.State.ONLINE) {
str.append(getResources().getString(R.string.status_online)+" ");
if (details.reachability == ComputerDetails.Reachability.LOCAL) {
str.append("("+getResources().getString(R.string.status_local)+") - ");
}
else {
str.append("("+getResources().getString(R.string.status_remote)+") - ");
}
if (details.pairState == PairState.PAIRED) {
if (details.runningGameId == 0) {
str.append(getResources().getString(R.string.status_available));
}
else {
str.append(getResources().getString(R.string.status_ingame));
}
}
else {
str.append(getResources().getString(R.string.status_not_paired));
}
}
else {
str.append(getResources().getString(R.string.status_offline));
}
return str.toString();
}
private void addListPlaceholder() {
pcListAdapter.add(new ComputerObject(getResources().getString(R.string.discovery_running), null));
}
private void removeListView(ComputerDetails details) {
for (int i = 0; i < pcListAdapter.getCount(); i++) {
ComputerObject computer = pcListAdapter.getItem(i);
if (details.equals(computer.details)) { if (details.equals(computer.details)) {
pcListAdapter.remove(computer); pcGridAdapter.removeComputer(computer);
break; break;
} }
} }
if (pcListAdapter.getCount() == 0) {
// Add the placeholder if we're down to 0 computers
addListPlaceholder();
}
} }
private void updateListView(ComputerDetails details) { private void updateComputer(ComputerDetails details) {
String computerString = generateString(details);
ComputerObject existingEntry = null; ComputerObject existingEntry = null;
boolean placeholderPresent = false;
for (int i = 0; i < pcListAdapter.getCount(); i++) { for (int i = 0; i < pcGridAdapter.getCount(); i++) {
ComputerObject computer = pcListAdapter.getItem(i); ComputerObject computer = (ComputerObject) pcGridAdapter.getItem(i);
// If there's a placeholder, there's nothing else
if (computer.details == null) {
placeholderPresent = true;
break;
}
// Check if this is the same computer // Check if this is the same computer
if (details.equals(computer.details)) { if (details.equals(computer.details)) {
@@ -584,35 +540,30 @@ public class PcView extends Activity {
if (existingEntry != null) { if (existingEntry != null) {
// Replace the information in the existing entry // Replace the information in the existing entry
existingEntry.text = computerString;
existingEntry.details = details; existingEntry.details = details;
} }
else { else {
// If the placeholder is the only object, remove it
if (placeholderPresent) {
pcListAdapter.remove(pcListAdapter.getItem(0));
}
// Add a new entry // Add a new entry
pcListAdapter.add(new ComputerObject(computerString, details)); pcGridAdapter.addComputer(new ComputerObject(details));
// Remove the "Discovery in progress" view
noPcFoundLayout.setVisibility(View.INVISIBLE);
} }
// Notify the view that the data has changed // Notify the view that the data has changed
pcListAdapter.notifyDataSetChanged(); pcGridAdapter.notifyDataSetChanged();
} }
public class ComputerObject { public class ComputerObject {
public String text;
public ComputerDetails details; public ComputerDetails details;
public ComputerObject(String text, ComputerDetails details) { public ComputerObject(ComputerDetails details) {
this.text = text;
this.details = details; this.details = details;
} }
@Override @Override
public String toString() { public String toString() {
return text; return details.name;
} }
} }
} }
@@ -100,6 +100,7 @@ public class ComputerDatabaseManager {
// This signifies we don't have dynamic state (like pair state) // This signifies we don't have dynamic state (like pair state)
details.state = ComputerDetails.State.UNKNOWN; details.state = ComputerDetails.State.UNKNOWN;
details.reachability = ComputerDetails.Reachability.UNKNOWN;
// If a field is corrupt or missing, skip the database entry // If a field is corrupt or missing, skip the database entry
if (details.uuid == null || details.localIp == null || details.remoteIp == null || if (details.uuid == null || details.localIp == null || details.remoteIp == null ||
@@ -107,6 +108,7 @@ public class ComputerDatabaseManager {
continue; continue;
} }
computerList.add(details); computerList.add(details);
} }
@@ -152,6 +154,9 @@ public class ComputerDatabaseManager {
c.close(); c.close();
details.state = ComputerDetails.State.UNKNOWN;
details.reachability = ComputerDetails.Reachability.UNKNOWN;
// If a field is corrupt or missing, delete the database entry // If a field is corrupt or missing, delete the database entry
if (details.uuid == null || details.localIp == null || details.remoteIp == null || if (details.uuid == null || details.localIp == null || details.remoteIp == null ||
details.macAddress == null) { details.macAddress == null) {
@@ -151,6 +151,9 @@ public class ComputerManagerService extends Service {
for (ComputerDetails computer : computerList) { for (ComputerDetails computer : computerList) {
// This polling thread might already be there // This polling thread might already be there
if (!pollingThreads.containsKey(computer)) { if (!pollingThreads.containsKey(computer)) {
// Report this computer initially
listener.notifyComputerUpdated(computer);
Thread t = createPollingThread(computer); Thread t = createPollingThread(computer);
pollingThreads.put(computer, t); pollingThreads.put(computer, t);
t.start(); t.start();
@@ -0,0 +1,167 @@
package com.limelight.grid;
import android.content.Context;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
import com.limelight.AppView;
import com.limelight.R;
import com.limelight.binding.PlatformBinding;
import com.limelight.nvstream.http.LimelightCryptoProvider;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.concurrent.Future;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
public class AppGridAdapter extends GenericGridAdapter<AppView.AppObject> {
private InetAddress address;
private String uniqueId;
private LimelightCryptoProvider cryptoProvider;
private SSLContext sslContext;
private HashMap<ImageView, Future> pendingRequests = new HashMap<ImageView, Future>();
public AppGridAdapter(Context context, InetAddress address, String uniqueId) throws NoSuchAlgorithmException, KeyManagementException {
super(context, R.layout.app_grid_item, R.drawable.image_loading);
this.address = address;
this.uniqueId = uniqueId;
cryptoProvider = PlatformBinding.getCryptoProvider(context);
sslContext = SSLContext.getInstance("SSL");
sslContext.init(ourKeyman, trustAllCerts, new SecureRandom());
}
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}};
KeyManager[] ourKeyman = new KeyManager[] {
new X509KeyManager() {
public String chooseClientAlias(String[] keyTypes,
Principal[] issuers, Socket socket) {
return "Limelight-RSA";
}
public String chooseServerAlias(String keyType, Principal[] issuers,
Socket socket) {
return null;
}
public X509Certificate[] getCertificateChain(String alias) {
return new X509Certificate[] {cryptoProvider.getClientCertificate()};
}
public String[] getClientAliases(String keyType, Principal[] issuers) {
return null;
}
public PrivateKey getPrivateKey(String alias) {
return cryptoProvider.getClientPrivateKey();
}
public String[] getServerAliases(String keyType, Principal[] issuers) {
return null;
}
}
};
// Ignore differences between given hostname and certificate hostname
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
public void addApp(AppView.AppObject app) {
itemList.add(app);
}
public void abortPendingRequests() {
HashMap<ImageView, Future> tempMap;
synchronized (pendingRequests) {
// Copy the pending requests under a lock
tempMap = new HashMap<ImageView, Future>(pendingRequests);
}
for (Future f : tempMap.values()) {
f.cancel(true);
}
synchronized (pendingRequests) {
// Remove cancelled requests
for (ImageView v : tempMap.keySet()) {
pendingRequests.remove(v);
}
}
}
@Override
public boolean populateImageView(final ImageView imgView, AppView.AppObject obj) {
// Set SSL contexts correctly to allow us to authenticate
Ion.getDefault(imgView.getContext()).getHttpClient().getSSLSocketMiddleware().setTrustManagers(trustAllCerts);
Ion.getDefault(imgView.getContext()).getHttpClient().getSSLSocketMiddleware().setSSLContext(sslContext);
// Set off the deferred image load
synchronized (pendingRequests) {
Future f = Ion.with(imgView)
.placeholder(defaultImageRes)
.error(defaultImageRes)
.load("https://" + address.getHostAddress() + ":47984/appasset?uniqueid=" + uniqueId + "&appid=" +
obj.app.getAppId() + "&AssetType=2&AssetIdx=0")
.setCallback(new FutureCallback<ImageView>() {
@Override
public void onCompleted(Exception e, ImageView result) {
synchronized (pendingRequests) {
pendingRequests.remove(imgView);
}
}
});
pendingRequests.put(imgView, f);
}
return true;
}
@Override
public boolean populateTextView(TextView txtView, AppView.AppObject obj) {
// Return false to use the app's toString method
return false;
}
@Override
public boolean populateOverlayView(ImageView overlayView, AppView.AppObject obj) {
if (obj.app.getIsRunning()) {
// Show the play button overlay
overlayView.setImageResource(R.drawable.play);
return true;
}
// No overlay
return false;
}
}
@@ -0,0 +1,79 @@
package com.limelight.grid;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.limelight.PcView;
import com.limelight.R;
import java.util.ArrayList;
public abstract class GenericGridAdapter<T> extends BaseAdapter {
protected Context context;
protected int defaultImageRes;
protected int layoutId;
protected ArrayList<T> itemList = new ArrayList<T>();
protected LayoutInflater inflater;
public GenericGridAdapter(Context context, int layoutId, int defaultImageRes) {
this.context = context;
this.layoutId = layoutId;
this.defaultImageRes = defaultImageRes;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void clear() {
itemList.clear();
}
@Override
public int getCount() {
return itemList.size();
}
@Override
public Object getItem(int i) {
return itemList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
public abstract boolean populateImageView(ImageView imgView, T obj);
public abstract boolean populateTextView(TextView txtView, T obj);
public abstract boolean populateOverlayView(ImageView overlayView, T obj);
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
if (convertView == null) {
convertView = inflater.inflate(layoutId, viewGroup, false);
}
ImageView imgView = (ImageView) convertView.findViewById(R.id.grid_image);
ImageView overlayView = (ImageView) convertView.findViewById(R.id.grid_overlay);
TextView txtView = (TextView) convertView.findViewById(R.id.grid_text);
if (!populateImageView(imgView, itemList.get(i))) {
imgView.setImageResource(defaultImageRes);
}
if (!populateTextView(txtView, itemList.get(i))) {
txtView.setText(itemList.get(i).toString());
}
if (!populateOverlayView(overlayView, itemList.get(i))) {
overlayView.setVisibility(View.INVISIBLE);
}
else {
overlayView.setVisibility(View.VISIBLE);
}
return convertView;
}
}
@@ -0,0 +1,62 @@
package com.limelight.grid;
import android.content.Context;
import android.widget.ImageView;
import android.widget.TextView;
import com.limelight.PcView;
import com.limelight.R;
import com.limelight.nvstream.http.ComputerDetails;
public class PcGridAdapter extends GenericGridAdapter<PcView.ComputerObject> {
public PcGridAdapter(Context context) {
super(context, R.layout.pc_grid_item, R.drawable.computer);
}
public void addComputer(PcView.ComputerObject computer) {
itemList.add(computer);
}
public boolean removeComputer(PcView.ComputerObject computer) {
return itemList.remove(computer);
}
@Override
public boolean populateImageView(ImageView imgView, PcView.ComputerObject obj) {
if (obj.details.reachability != ComputerDetails.Reachability.OFFLINE) {
imgView.setAlpha(1.0f);
}
else {
imgView.setAlpha(0.4f);
}
// Return false to use the default drawable
return false;
}
@Override
public boolean populateTextView(TextView txtView, PcView.ComputerObject obj) {
if (obj.details.reachability != ComputerDetails.Reachability.OFFLINE) {
txtView.setAlpha(1.0f);
}
else {
txtView.setAlpha(0.4f);
}
// Return false to use the computer's toString method
return false;
}
@Override
public boolean populateOverlayView(ImageView overlayView, PcView.ComputerObject obj) {
if (obj.details.reachability == ComputerDetails.Reachability.UNKNOWN) {
// Still refreshing this PC so display the overlay
overlayView.setImageResource(R.drawable.image_loading);
return true;
}
// No overlay
return false;
}
}
@@ -7,6 +7,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import com.limelight.computers.ComputerManagerService; import com.limelight.computers.ComputerManagerService;
import com.limelight.R; import com.limelight.R;
import com.limelight.utils.Dialog; import com.limelight.utils.Dialog;
import com.limelight.utils.SpinnerDialog;
import com.limelight.utils.UiHelper; import com.limelight.utils.UiHelper;
import android.app.Activity; import android.app.Activity;
@@ -16,14 +17,17 @@ import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.Button; import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
public class AddComputerManually extends Activity { public class AddComputerManually extends Activity {
private Button addPcButton;
private TextView hostText; private TextView hostText;
private ComputerManagerService.ComputerManagerBinder managerBinder; private ComputerManagerService.ComputerManagerBinder managerBinder;
private LinkedBlockingQueue<String> computersToAdd = new LinkedBlockingQueue<String>(); private LinkedBlockingQueue<String> computersToAdd = new LinkedBlockingQueue<String>();
@@ -43,6 +47,9 @@ public class AddComputerManually extends Activity {
private void doAddPc(String host) { private void doAddPc(String host) {
String msg; String msg;
boolean finish = false; boolean finish = false;
SpinnerDialog dialog = SpinnerDialog.displayDialog(this, "Add PC Manually", "Connecting to the specified PC...", false);
try { try {
InetAddress addr = InetAddress.getByName(host); InetAddress addr = InetAddress.getByName(host);
@@ -57,6 +64,8 @@ public class AddComputerManually extends Activity {
msg = getResources().getString(R.string.addpc_unknown_host); msg = getResources().getString(R.string.addpc_unknown_host);
} }
dialog.dismiss();
final boolean toastFinish = finish; final boolean toastFinish = finish;
final String toastMsg = msg; final String toastMsg = msg;
AddComputerManually.this.runOnUiThread(new Runnable() { AddComputerManually.this.runOnUiThread(new Runnable() {
@@ -110,6 +119,7 @@ public class AddComputerManually extends Activity {
super.onStop(); super.onStop();
Dialog.closeDialogs(); Dialog.closeDialogs();
SpinnerDialog.closeDialogs(this);
} }
@Override @Override
@@ -130,24 +140,28 @@ public class AddComputerManually extends Activity {
UiHelper.notifyNewRootView(this); UiHelper.notifyNewRootView(this);
this.addPcButton = (Button) findViewById(R.id.addPc);
this.hostText = (TextView) findViewById(R.id.hostTextView); this.hostText = (TextView) findViewById(R.id.hostTextView);
hostText.setImeOptions(EditorInfo.IME_ACTION_DONE);
hostText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if (actionId == EditorInfo.IME_ACTION_DONE ||
keyEvent.getAction() == KeyEvent.ACTION_DOWN &&
keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
if (hostText.getText().length() == 0) {
Toast.makeText(AddComputerManually.this, getResources().getString(R.string.addpc_enter_ip), Toast.LENGTH_LONG).show();
return true;
}
computersToAdd.add(hostText.getText().toString());
}
return false;
}
});
// Bind to the ComputerManager service // Bind to the ComputerManager service
bindService(new Intent(AddComputerManually.this, bindService(new Intent(AddComputerManually.this,
ComputerManagerService.class), serviceConnection, Service.BIND_AUTO_CREATE); ComputerManagerService.class), serviceConnection, Service.BIND_AUTO_CREATE);
addPcButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (hostText.getText().length() == 0) {
Toast.makeText(AddComputerManually.this, getResources().getString(R.string.addpc_enter_ip), Toast.LENGTH_LONG).show();
return;
}
Toast.makeText(AddComputerManually.this, getResources().getString(R.string.addpc_adding_pc), Toast.LENGTH_SHORT).show();
computersToAdd.add(hostText.getText().toString());
}
});
} }
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke android:width="1dip" android:color="#ffffff"/>
</shape>
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@@ -8,48 +8,64 @@
android:paddingTop="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".PcView" > tools:context=".PcView" >
<ListView <RelativeLayout
android:id="@+id/pcListView" android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/manuallyAddPc"
android:layout_toRightOf="@+id/settingsButton">
<GridView
android:id="@+id/pcGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numColumns="auto_fit"
android:columnWidth="160dp"
android:gravity="center"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true" android:layout_alignParentTop="true"/>
android:layout_alignParentRight="true" <RelativeLayout
android:layout_below="@+id/settingsButton" android:id="@+id/no_pc_found_layout"
android:background="@drawable/list_view_unselected" android:layout_width="wrap_content"
android:fastScrollEnabled="true" android:layout_height="wrap_content"
android:longClickable="false" android:layout_centerInParent="true"
android:stackFromBottom="false" > android:layout_centerVertical="true"
android:layout_centerHorizontal="true">
</ListView> <ImageView
android:id="@+id/pcs_loading"
android:layout_width="75dp"
android:layout_height="75dp"
android:src="@drawable/image_loading"/>
<TextView <TextView
android:id="@+id/discoveryText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="@+id/pcs_loading"
android:layout_marginLeft="5dp"
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_centerHorizontal="true" android:gravity="center"
android:layout_alignBaseline="@+id/settingsButton" android:text="Searching for PCs on the network..."/>
android:text="@string/title_pc_view" /> </RelativeLayout>
</RelativeLayout>
<Button <ImageButton
android:id="@+id/settingsButton" android:id="@+id/settingsButton"
android:layout_width="wrap_content" android:layout_width="70dp"
android:layout_height="wrap_content" android:layout_height="65dp"
android:layout_alignLeft="@+id/pcListView" android:cropToPadding="false"
android:scaleType="fitXY"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_marginTop="10dp" android:src="@drawable/settings"
android:layout_marginBottom="15dp" style="?android:attr/borderlessButtonStyle"/>
android:text="@string/button_stream_settings" />
<Button <ImageButton
android:id="@+id/manuallyAddPc" android:id="@+id/manuallyAddPc"
android:layout_width="wrap_content" android:layout_width="70dp"
android:layout_height="wrap_content" android:layout_height="65dp"
android:layout_alignRight="@+id/pcListView" android:cropToPadding="false"
android:scaleType="fitXY"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_marginTop="10dp" android:layout_alignParentRight="true"
android:layout_marginBottom="15dp" android:src="@drawable/add_computer"
android:text="@string/button_add_pc_manually" /> style="?android:attr/borderlessButtonStyle"/>
</RelativeLayout> </RelativeLayout>
@@ -8,46 +8,64 @@
android:paddingTop="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".PcView" > tools:context=".PcView" >
<ListView <RelativeLayout
android:id="@+id/pcListView" android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/manuallyAddPc"
android:layout_toRightOf="@+id/settingsButton">
<GridView
android:id="@+id/pcGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numColumns="auto_fit"
android:columnWidth="160dp"
android:gravity="center"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true" android:layout_alignParentTop="true"/>
android:layout_alignParentRight="true" <RelativeLayout
android:layout_below="@+id/discoveryText" android:id="@+id/no_pc_found_layout"
android:background="@drawable/list_view_unselected" android:layout_width="wrap_content"
android:fastScrollEnabled="true" android:layout_height="wrap_content"
android:longClickable="false" android:layout_centerInParent="true"
android:stackFromBottom="false" > android:layout_centerVertical="true"
android:layout_centerHorizontal="true">
</ListView> <ImageView
android:id="@+id/pcs_loading"
android:layout_width="75dp"
android:layout_height="75dp"
android:src="@drawable/image_loading"/>
<TextView <TextView
android:id="@+id/discoveryText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:layout_toRightOf="@+id/pcs_loading"
android:layout_marginLeft="5dp"
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_below="@+id/manuallyAddPc" android:gravity="center"
android:paddingTop="10dp" android:text="Searching for PCs on the network..."/>
android:paddingBottom="10dp" </RelativeLayout>
android:text="@string/title_pc_view" /> </RelativeLayout>
<Button <ImageButton
android:id="@+id/settingsButton" android:id="@+id/settingsButton"
android:layout_width="wrap_content" android:layout_width="70dp"
android:layout_height="wrap_content" android:layout_height="65dp"
android:layout_centerHorizontal="true" android:cropToPadding="false"
android:scaleType="fitXY"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:text="@string/button_stream_settings" /> android:src="@drawable/settings"
style="?android:attr/borderlessButtonStyle"/>
<Button <ImageButton
android:id="@+id/manuallyAddPc" android:id="@+id/manuallyAddPc"
android:layout_width="wrap_content" android:layout_width="70dp"
android:layout_height="wrap_content" android:layout_height="65dp"
android:layout_below="@+id/settingsButton" android:cropToPadding="false"
android:layout_centerHorizontal="true" android:scaleType="fitXY"
android:text="@string/button_add_pc_manually" /> android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:src="@drawable/add_computer"
style="?android:attr/borderlessButtonStyle"/>
</RelativeLayout> </RelativeLayout>
@@ -5,16 +5,26 @@
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="10dp" android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".Connection" > tools:context=".AddComputerManually" >
<TextView
android:id="@+id/manuallyAddPcText"
android:text="@string/title_add_pc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_alignParentTop="true"/>
<EditText <EditText
android:id="@+id/hostTextView" android:id="@+id/hostTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/manuallyAddPcText"
android:layout_marginTop="25dp"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:ems="10" android:ems="10"
android:singleLine="true" android:singleLine="true"
android:inputType="textNoSuggestions" android:inputType="textNoSuggestions"
@@ -23,12 +33,4 @@
<requestFocus /> <requestFocus />
</EditText> </EditText>
<Button
android:id="@+id/addPc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/hostTextView"
android:layout_centerHorizontal="true"
android:text="@string/button_add_pc" />
</RelativeLayout> </RelativeLayout>
@@ -8,19 +8,18 @@
android:paddingTop="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".AppView" > tools:context=".AppView" >
<ListView <GridView
android:id="@+id/pcListView" android:id="@+id/appGridView"
android:layout_width="match_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:numColumns="auto_fit"
android:columnWidth="160dp"
android:gravity="center"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_below="@+id/appListText" android:layout_below="@+id/appListText">
android:fastScrollEnabled="true" </GridView>
android:longClickable="false"
android:background="@drawable/list_view_unselected"
android:stackFromBottom="false">
</ListView>
<TextView <TextView
android:id="@+id/appListText" android:id="@+id/appListText"
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="30dp">
<RelativeLayout
android:id="@+id/grid_image_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/grid_image"
android:layout_centerHorizontal="true"
android:layout_width="100dp"
android:layout_height="150dp">
</ImageView>
<ImageView
android:id="@+id/grid_overlay"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_width="50dp"
android:layout_height="50dp">
</ImageView>
</RelativeLayout>
<TextView
android:id="@+id/grid_text"
android:layout_width="125dp"
android:layout_height="wrap_content"
android:layout_below="@id/grid_image_layout"
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true"
android:gravity="center"
android:textSize="20sp" >
</TextView>
</RelativeLayout>
+35
View File
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp">
<RelativeLayout
android:id="@+id/grid_image_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/grid_image"
android:layout_centerHorizontal="true"
android:layout_width="150dp"
android:layout_height="100dp">
</ImageView>
<ImageView
android:id="@+id/grid_overlay"
android:layout_marginTop="15dp"
android:layout_marginLeft="65dp"
android:layout_marginRight="20dp"
android:layout_width="50dp"
android:layout_height="50dp">
</ImageView>
</RelativeLayout>
<TextView
android:id="@+id/grid_text"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_below="@id/grid_image_layout"
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true"
android:gravity="center"
android:textSize="20sp" >
</TextView>
</RelativeLayout>
-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:padding="10dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/rowTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false"
android:textSize="16sp" >
</TextView>
</LinearLayout>
+15 -14
View File
@@ -43,13 +43,13 @@
</string> </string>
<!-- Status info --> <!-- Status info -->
<string name="status_online">Online</string> <!--<string name="status_online">Online</string>
<string name="status_offline">Offline</string> <string name="status_offline">Offline</string>
<string name="status_local">Local</string> <string name="status_local">Local</string>
<string name="status_remote">Remote</string> <string name="status_remote">Remote</string>
<string name="status_available">Available</string> <string name="status_available">Available</string>
<string name="status_ingame">In Game</string> <string name="status_ingame">In Game</string>
<string name="status_not_paired">Not Paired</string> <string name="status_not_paired">Not Paired</string>-->
<!-- Start application messages --> <!-- Start application messages -->
<string name="conn_establishing_title">Establishing Connection</string> <string name="conn_establishing_title">Establishing Connection</string>
@@ -61,37 +61,37 @@
<string name="conn_starting">Starting</string> <string name="conn_starting">Starting</string>
<string name="conn_error_title">Connection Error</string> <string name="conn_error_title">Connection Error</string>
<string name="conn_error_msg">Fail starting</string> <string name="conn_error_msg">Fail starting</string>
<string name="conn_fail_title">Connection Terminated</string> <string name="conn_terminated_title">Connection Terminated</string>
<string name="conn_fail_msg">The connection failed unexpectedly</string> <string name="conn_terminated_msg">The connection was terminated</string>
<!-- Add computer manually messages --> <!-- Add computer manually messages -->
<string name="addpc_fail">Unable to connect to the specified computer. Make sure the required ports are allowed through the firewall.</string> <string name="addpc_fail">Unable to connect to the specified computer. Make sure the required ports are allowed through the firewall.</string>
<string name="addpc_success">Successfully added computer</string> <string name="addpc_success">Successfully added computer</string>
<string name="addpc_unknown_host">Unable to resolve PC address. Make sure you didn\'t make a typo in the address.</string> <string name="addpc_unknown_host">Unable to resolve PC address. Make sure you didn\'t make a typo in the address.</string>
<string name="addpc_enter_ip">You must enter an IP address</string> <string name="addpc_enter_ip">You must enter an IP address</string>
<string name="addpc_adding_pc">Adding PC...</string> <!--<string name="addpc_adding_pc">Adding PC...</string>-->
<!-- General strings --> <!-- General strings -->
<string name="discovery_running">Discovery is running. No computers found yet. If your PC doesn't show up in about 15 seconds, <!--<string name="discovery_running">Discovery is running. No computers found yet. If your PC doesn't show up in about 15 seconds,
make sure your computer is running GFE or add your PC manually using the button above. make sure your computer is running GFE or add your PC manually using the button above.
</string> </string>-->
<string name="ip_hint">IP address of GeForce PC</string> <string name="ip_hint">IP address of GeForce PC</string>
<!-- PC view activity --> <!-- PC view activity -->
<string name="title_pc_view">PC List</string> <!--<string name="title_pc_view">PC List</string>
<string name="button_stream_settings">Streaming Settings</string> <string name="button_stream_settings">Streaming Settings</string>
<string name="button_add_pc_manually">Add PC Manually</string> <string name="button_add_pc_manually">Add PC Manually</string>-->
<!-- AppList activity --> <!-- AppList activity -->
<string name="title_applist">App List for</string> <string name="title_applist">Apps on</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_app_running">Running</string> <!--<string name="applist_app_running">Running</string>-->
<string name="applist_no_apps">No apps found. Try rescanningfor games in GeForce Experience.</string> <!--<string name="applist_no_apps">No apps found. Try rescanningfor games in GeForce Experience.</string>-->
<string name="applist_refersh_title">App List</string> <string name="applist_refersh_title">App List</string>
<string name="applist_refresh_msg">Refreshing app list...</string> <string name="applist_refresh_msg">Refreshing apps...</string>
<string name="applist_refersh_error_title">Error</string> <string name="applist_refersh_error_title">Error</string>
<string name="applist_refersh_error_msg">Failed to get app list</string> <string name="applist_refersh_error_msg">Failed to get app list</string>
<string name="applist_quit_app">Quitting</string> <string name="applist_quit_app">Quitting</string>
@@ -99,7 +99,8 @@
<string name="applist_quit_fail">Failed to quit</string> <string name="applist_quit_fail">Failed to quit</string>
<!-- Add computer manually activity --> <!-- Add computer manually activity -->
<string name="button_add_pc">Manually Add PC</string> <string name="title_add_pc">Add PC Manually</string>
<string name="button_add_pc">Add PC</string>
<!-- Preferences --> <!-- Preferences -->
<string name="category_basic_settings">Basic Settings</string> <string name="category_basic_settings">Basic Settings</string>