[Android] Don't crash on non-neon devices.

Ludovic Fauvet git at videolan.org
Mon Jul 2 02:35:04 CEST 2012


android | branch: master | Ludovic Fauvet <etix at videolan.org> | Mon Jul  2 02:29:03 2012 +0200| [bf35296c2251505aae3c63baef831d9d350940a1] | committer: Ludovic Fauvet

Don't crash on non-neon devices.

This commit also send the model of unsupported devices to a webservice
so we're able to exclude them from the beta.
This commit needs to be reverted for builds _without_ NEON support.

> http://git.videolan.org/gitweb.cgi/android.git/?a=commit;h=bf35296c2251505aae3c63baef831d9d350940a1
---

 vlc-android/AndroidManifest.xml                    |    3 +
 vlc-android/res/layout/no_neon.xml                 |   31 +++++++++
 vlc-android/res/values/strings.xml                 |    1 +
 vlc-android/src/org/videolan/vlc/LibVLC.java       |    6 ++
 vlc-android/src/org/videolan/vlc/Util.java         |   22 +++++++
 .../org/videolan/vlc/gui/CompatErrorActivity.java  |   68 ++++++++++++++++++++
 .../src/org/videolan/vlc/gui/MainActivity.java     |   14 +++-
 7 files changed, 144 insertions(+), 1 deletion(-)

diff --git a/vlc-android/AndroidManifest.xml b/vlc-android/AndroidManifest.xml
index cf0f399..540c0b2 100644
--- a/vlc-android/AndroidManifest.xml
+++ b/vlc-android/AndroidManifest.xml
@@ -33,6 +33,9 @@
             </intent-filter>
         </activity>
         <activity
+            android:name=".gui.CompatErrorActivity"
+            android:theme="@android:style/Theme.NoTitleBar" />
+        <activity
             android:name=".gui.SearchActivity"
             android:configChanges="orientation|screenSize"
             android:theme="@android:style/Theme.NoTitleBar"
diff --git a/vlc-android/res/layout/no_neon.xml b/vlc-android/res/layout/no_neon.xml
new file mode 100644
index 0000000..89d8ef8
--- /dev/null
+++ b/vlc-android/res/layout/no_neon.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent"
+	android:layout_height="match_parent"
+	android:background="#000">
+	
+	<LinearLayout
+		android:layout_width="match_parent"
+		android:layout_height="wrap_content"
+		android:orientation="vertical">
+
+		<ImageView
+			android:id="@+id/logo"
+			android:layout_width="130dp"
+			android:layout_height="wrap_content"
+			android:scaleType="centerInside"
+			android:layout_gravity="center_horizontal"
+			android:contentDescription="@string/info"
+			android:src="@drawable/cone" />
+	
+		<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_gravity="center_horizontal"
+			android:text="@string/error_no_neon"
+			android:textColor="#FF0000"
+			android:textSize="20dp" />
+	
+	</LinearLayout>
+	
+</ScrollView>
\ No newline at end of file
diff --git a/vlc-android/res/values/strings.xml b/vlc-android/res/values/strings.xml
index 3cdac27..cc5b9bd 100644
--- a/vlc-android/res/values/strings.xml
+++ b/vlc-android/res/values/strings.xml
@@ -131,4 +131,5 @@
         <item>@string/aout_audiotrack</item>
         <item>@string/aout_opensles</item>
     </string-array>
+    <string name="error_no_neon">Sorry but your device is currently not supported by VLC for Android™</string>
 </resources>
diff --git a/vlc-android/src/org/videolan/vlc/LibVLC.java b/vlc-android/src/org/videolan/vlc/LibVLC.java
index c96017e..cd9444f 100644
--- a/vlc-android/src/org/videolan/vlc/LibVLC.java
+++ b/vlc-android/src/org/videolan/vlc/LibVLC.java
@@ -20,6 +20,8 @@
 
 package org.videolan.vlc;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 
 import org.videolan.vlc.gui.video.VideoPlayerActivity;
@@ -178,6 +180,10 @@ public class LibVLC {
     private void init() throws LibVlcException {
         Log.v(TAG, "Initializing LibVLC");
         if (!mIsInitialized) {
+            if (!Util.hasNeon()) {
+                Log.e(TAG, "Required CPU feature is missing.");
+                return;
+            }
             Context context = VLCApplication.getAppContext();
             SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
             nativeInit(pref.getBoolean("enable_verbose_mode", true));
diff --git a/vlc-android/src/org/videolan/vlc/Util.java b/vlc-android/src/org/videolan/vlc/Util.java
index 1e7573c..55b92ab 100644
--- a/vlc-android/src/org/videolan/vlc/Util.java
+++ b/vlc-android/src/org/videolan/vlc/Util.java
@@ -184,4 +184,26 @@ public class Util {
     {
         return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
     }
+
+    public static boolean hasNeon()
+    {
+        ProcessBuilder cmd;
+
+        try {
+            String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
+            cmd = new ProcessBuilder(args);
+
+            Process process = cmd.start();
+            InputStream in = process.getInputStream();
+            byte[] re = new byte[1024];
+            while(in.read(re) != -1){
+                if (new String(re).contains("neon"))
+                    return true;
+            }
+            in.close();
+        } catch(IOException ex){
+            ex.printStackTrace();
+        }
+        return false;
+    }
 }
diff --git a/vlc-android/src/org/videolan/vlc/gui/CompatErrorActivity.java b/vlc-android/src/org/videolan/vlc/gui/CompatErrorActivity.java
new file mode 100644
index 0000000..964096d
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/CompatErrorActivity.java
@@ -0,0 +1,68 @@
+package org.videolan.vlc.gui;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.videolan.vlc.R;
+import android.app.Activity;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+
+public class CompatErrorActivity extends Activity {
+    public final static String TAG = "VLC/CompatErrorActivity";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        setContentView(R.layout.no_neon);
+        super.onCreate(savedInstanceState);
+
+        AsyncHttpRequest asyncHttpRequest = new AsyncHttpRequest();
+        asyncHttpRequest.execute(Build.MODEL, Build.DEVICE);
+    }
+
+    public class AsyncHttpRequest extends AsyncTask<String, String, Boolean> {
+
+        public AsyncHttpRequest() { }
+
+        @Override
+        protected Boolean doInBackground(String... params) {
+            if (params[0].length() == 0)
+                return false;
+            HttpClient httpClient = new DefaultHttpClient();
+            HttpPost httpPost = new HttpPost("http://people.videolan.org/~jb/blacklist/vlc-devices.php");
+
+            try {
+                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
+                nameValuePairs.add(new BasicNameValuePair("model", params[0]));
+                nameValuePairs.add(new BasicNameValuePair("device", params[1]));
+                httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
+
+                httpClient.execute(httpPost);
+            } catch (ClientProtocolException e) {
+                e.printStackTrace();
+                return false;
+            } catch (IOException e) {
+                e.printStackTrace();
+                return false;
+            }
+            Log.d(TAG, "Device model sent.");
+            return true;
+        }
+
+        @Override
+        protected void onPostExecute(Boolean result) {
+
+        }
+    }
+}
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index 0f27ea7..f9720b0 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
 import org.videolan.vlc.AudioService;
 import org.videolan.vlc.AudioServiceController;
 import org.videolan.vlc.LibVLC;
+import org.videolan.vlc.LibVlcException;
 import org.videolan.vlc.MediaLibrary;
 import org.videolan.vlc.R;
 import org.videolan.vlc.Util;
@@ -97,6 +98,15 @@ public class MainActivity extends SherlockFragmentActivity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
+        if (!Util.hasNeon()) {
+            Log.e(TAG, "CPU is missing NEON.");
+            super.onCreate(savedInstanceState);
+            Intent i = new Intent(this, CompatErrorActivity.class);
+            startActivity(i);
+            finish();
+            return;
+        }
+
         if (Util.isICSOrLater()) /* Bug on pre-ICS, the progress bar is always present */
             requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
         setContentView(R.layout.main);
@@ -210,7 +220,9 @@ public class MainActivity extends SherlockFragmentActivity {
 
     @Override
     protected void onDestroy() {
-        unregisterReceiver(messageReceiver);
+        try {
+            unregisterReceiver(messageReceiver);
+        } catch (IllegalArgumentException e) {}
         super.onDestroy();
     }
 



More information about the Android mailing list