Show game data version
[louyapi.git] / src / main / java / de / cweiske / ouya / louyapi / MainActivity.java
1 package de.cweiske.ouya.louyapi;
2
3 import android.app.Activity;
4 import android.content.Context;
5 import android.content.Intent;
6 import android.content.res.AssetManager;
7 import android.net.ConnectivityManager;
8 import android.net.NetworkInfo;
9 import android.net.wifi.WifiManager;
10 import android.os.Bundle;
11 import android.os.Environment;
12 import android.view.View;
13 import android.widget.Button;
14 import android.widget.TextView;
15 import android.widget.Toast;
16
17 import java.io.BufferedReader;
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.FileOutputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.InputStreamReader;
24 import java.io.OutputStream;
25 import java.net.InetAddress;
26 import java.net.NetworkInterface;
27 import java.net.SocketException;
28 import java.nio.Buffer;
29 import java.text.SimpleDateFormat;
30 import java.util.Date;
31 import java.util.Enumeration;
32 import java.util.Locale;
33 import java.util.Properties;
34
35 public class MainActivity extends Activity {
36
37     private static final String TAG = "louyapi-ui";
38
39     protected Intent serviceIntent;
40
41     protected String configFilePath;
42     protected String configFileBackupPath;
43     protected String gameDataVersion;
44
45     @Override
46     protected void onCreate(Bundle savedInstanceState) {
47         super.onCreate(savedInstanceState);
48         setContentView(R.layout.activity_main);
49
50         serviceIntent = new Intent(this, HttpService.class);
51         startService(serviceIntent);
52
53         configFilePath = Environment.getExternalStorageDirectory().getPath() + "/ouya_config.properties";
54         configFileBackupPath = Environment.getExternalStorageDirectory().getPath() + "/ouya_config.properties.backup";
55
56         loadGameDataVersion();
57         loadStatus();
58     }
59
60     protected void loadGameDataVersion() {
61         try {
62             InputStream is = getAssets().open("stouyapi-www/game-data-version", AssetManager.ACCESS_BUFFER);
63             gameDataVersion = new BufferedReader(new InputStreamReader(is)).readLine();
64         } catch (IOException e) {
65             gameDataVersion = "unknown";
66         }
67     }
68
69     protected void loadStatus() {
70         TextView statusGameDataVersion = (TextView) findViewById(R.id.statusGameDataVersion);
71         statusGameDataVersion.setText(gameDataVersion);
72
73         TextView statusPortNumber = (TextView) findViewById(R.id.statusPortNumber);
74         statusPortNumber.setText("8080");
75
76         TextView statusCurrentServer = (TextView) findViewById(R.id.statusCurrentServer);
77         String currentServer = loadCurrentServer();
78         if (currentServer == null) {
79             statusCurrentServer.setText("https://devs.ouya.tv/ (default)");
80         } else {
81             statusCurrentServer.setText(currentServer);
82         }
83
84         TextView statusIpAddress = (TextView) findViewById(R.id.statusIpAddress);
85         statusIpAddress.setText(getCurrentIpAddressStatus());
86
87         Button useDefault = (Button) findViewById(R.id.buttonUseDefault);
88         Button backupCreate = (Button) findViewById(R.id.buttonBackupCreate);
89         File conf = new File(configFilePath);
90         useDefault.setEnabled(conf.exists());
91         backupCreate.setEnabled(conf.exists());
92
93         Button backupRestore = (Button) findViewById(R.id.buttonBackupRestore);
94         TextView backupTime = (TextView) findViewById(R.id.backupDate);
95         File backup = new File(configFileBackupPath);
96         backupRestore.setEnabled(backup.exists());
97         if (backup.exists()) {
98             Date modified = new Date(backup.lastModified());
99             SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss z");
100             backupTime.setText(sdf.format(modified));
101         } else {
102             backupTime.setText("");
103         }
104     }
105
106     /**
107      * This got much more complicated than I anticipated :(
108      *
109      * @return The current IPv4 address plus the connection type
110      */
111     private String getCurrentIpAddressStatus() {
112         ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
113         if (cm == null) {
114             return "Unknown";
115         }
116
117         NetworkInfo info = cm.getActiveNetworkInfo();
118         if (info == null) {
119             return "No network connection";
120         }
121         if (info.getType() == ConnectivityManager.TYPE_WIFI) {
122             WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
123             int ip = wifi != null ? wifi.getConnectionInfo().getIpAddress() : 0;
124             if (ip != 0) {
125                 String ipStr = formatIp(ip);
126                 return ipStr + " (WiFi)";
127             }
128             return "WiFi";
129
130         } else if (info.getType() == ConnectivityManager.TYPE_ETHERNET) {
131             try {
132                 NetworkInterface eth0 = null;
133                 Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
134                 while (interfaces.hasMoreElements()) {
135                     NetworkInterface networkInterface = interfaces.nextElement();
136                     if (networkInterface.getName().equals("eth0")) {
137                         eth0 = networkInterface;
138                     }
139                 }
140                 if (eth0 == null) {
141                     return "unknown (Ethernet)";
142                 }
143
144                 Enumeration<InetAddress> addresses = eth0.getInetAddresses();
145                 while (addresses.hasMoreElements()) {
146                     InetAddress address = addresses.nextElement();
147                     //I found that this gave me the correct IPv4 address
148                     if (address.isSiteLocalAddress()) {
149                         return address.getHostAddress() + " (Ethernet)";
150                     }
151                 }
152
153                 return "unknown (Ethernet)";
154             } catch (SocketException e) {
155                 return "unknown (Ethernet)";
156             }
157
158         } else {
159             return "unknown (" + info.getTypeName() + ")";
160         }
161     }
162
163     protected String loadCurrentServer()
164     {
165         Properties props = new Properties();
166         try {
167             FileInputStream in = new FileInputStream(configFilePath);
168             props.load(in);
169         } catch (Exception e) {
170             return null;
171         }
172
173         return props.getProperty("OUYA_SERVER_URL", null);
174     }
175
176     public void onClickExit(View view) {
177         this.finish();
178     }
179
180     public void onClickBackupCreate(View view) {
181         if (copyFile(configFilePath, configFileBackupPath)) {
182             showInfo("Backup created.");
183         }
184         loadStatus();
185     }
186
187     public void onClickBackupRestore(View view) {
188         if (copyFile(configFileBackupPath, configFilePath)) {
189             showInfo("Backup restored.");
190         }
191         loadStatus();
192     }
193
194     private boolean copyFile(String source, String target) {
195         try {
196             InputStream in = new FileInputStream(source);
197             OutputStream out = new FileOutputStream(target);
198             byte[] buf = new byte[4096];
199             int len;
200             while ((len = in.read(buf)) > 0) {
201                 out.write(buf, 0, len);
202             }
203             in.close();
204             out.close();
205         } catch (IOException e) {
206             showError(e.getMessage());
207             return false;
208         }
209         return true;
210     }
211
212     public void onClickUseDefault(View view) {
213         File f = new File(configFilePath);
214         if (f.delete()) {
215             showInfo("Configuration file deleted");
216         } else {
217             showError("Could not delete configuration file");
218         }
219         loadStatus();
220     }
221
222     public void onClickUseLouyapi(View view) {
223         writeConfig("http://127.0.0.1:8080/", "http://127.0.0.1:8080/api/v1/status");
224         loadStatus();
225     }
226
227     public void onClickUseCweiske(View view) {
228         writeConfig("http://ouya.cweiske.de/", "http://ouya.cweiske.de/api/v1/status");
229         loadStatus();
230     }
231
232     private void writeConfig(String serverUrl, String statusUrl) {
233         String content = "OUYA_SERVER_URL=" + serverUrl + "\n"
234             + "OUYA_STATUS_SERVER_URL=" + statusUrl + "\n";
235         try {
236             FileOutputStream fos = new FileOutputStream(configFilePath);
237             fos.write(content.getBytes());
238             showInfo("Configuration written");
239         } catch (IOException e) {
240             showError(e.getMessage());
241         }
242     }
243
244     private void showInfo(String message) {
245         showError(message);
246     }
247
248     private void showError(String message) {
249         Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
250     }
251
252     protected String formatIp(int ip) {
253         return String.format(
254             Locale.ENGLISH,
255             "%d.%d.%d.%d",
256             (ip & 0xff),
257             (ip >> 8 & 0xff),
258             (ip >> 16 & 0xff),
259             (ip >> 24 & 0xff));
260     }
261
262     /**
263      * Why do we want to stop exactly the service that we want to keep alive?
264      * Because if we do not stop it, the service will die with our app.
265      * Instead, by stopping the service, we will force the service to call its
266      * own onDestroy which will force it to recreate itself after the app is dead.
267      */
268     protected void onDestroy() {
269         stopService(serviceIntent);
270         super.onDestroy();
271     }
272 }