Commit f0c44a0a authored by Paweł Wegner's avatar Paweł Wegner

cloudbrowser: refactored java interface.

parent 0dfea47a
......@@ -135,7 +135,10 @@ DISTFILES += \
src/org/videolan/cloudbrowser/NotificationHelper.java \
src/org/videolan/cloudbrowser/NotificationService.java \
build.gradle \
project.properties
project.properties \
src/org/videolan/cloudbrowser/FileInput.java \
src/org/videolan/cloudbrowser/Utility.java \
src/org/videolan/cloudbrowser/FileOutput.java
ANDROID_PACKAGE_SOURCE_DIR = $$PWD
......
......@@ -7,10 +7,7 @@ import android.content.Intent;
public class AuthView extends Activity {
private boolean m_intent_run = false;
public AuthView() {
CloudBrowser.m_auth_view = this;
}
public static AuthView m_current;
@Override
protected void onResume() {
......@@ -21,6 +18,8 @@ public class AuthView extends Activity {
null : intent_extras.getCharSequence("address");
String url = sequence == null ? null : sequence.toString();
m_current = this;
if (!m_intent_run) {
m_intent_run = true;
if (url != null) {
......
......@@ -7,15 +7,11 @@ import android.view.WindowManager;
import android.database.Cursor;
import android.provider.OpenableColumns;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.content.pm.ActivityInfo;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import org.qtproject.qt5.android.bindings.QtActivity;
import com.google.android.gms.ads.MobileAds;
......@@ -25,26 +21,12 @@ import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdListener;
public class CloudBrowser extends QtActivity {
private static CloudBrowser m_instance;
public static AuthView m_auth_view;
private AuthView m_auth_view;
private NotificationHelper m_notification_helper;
private ViewGroup m_view_group;
private RelativeLayout m_ad_view;
private boolean m_ad_view_visible = false;
public static class FileOutput {
public ParcelFileDescriptor m_descriptor;
public FileOutputStream m_stream;
}
public static class FileInput {
public ParcelFileDescriptor m_descriptor;
public FileInputStream m_stream;
}
public CloudBrowser() {
m_instance = this;
}
private void updateAdView() {
if (m_ad_view != null && m_view_group != null)
m_view_group.removeView(m_ad_view);
......@@ -91,7 +73,7 @@ public class CloudBrowser extends QtActivity {
public void onCreate(Bundle state) {
super.onCreate(state);
NotificationHelper.initialize();
m_notification_helper = new NotificationHelper(this);
MobileAds.initialize(this, "ca-app-pub-9966958697007244~3913638593");
View view = getWindow().getDecorView().getRootView();
......@@ -109,128 +91,75 @@ public class CloudBrowser extends QtActivity {
@Override
public void onDestroy() {
NotificationHelper.release();
m_notification_helper.release();
super.onDestroy();
}
public static CloudBrowser instance() {
return m_instance;
}
public static void showAd() {
m_instance.runOnUiThread(new Runnable() {
public void showAd() {
runOnUiThread(new Runnable() {
public void run() {
m_instance.m_ad_view_visible = true;
m_instance.updateAdView();
m_ad_view_visible = true;
updateAdView();
}
});
}
public static void hideAd() {
m_instance.runOnUiThread(new Runnable() {
public void hideAd() {
runOnUiThread(new Runnable() {
public void run() {
m_instance.m_ad_view_visible = false;
if (m_instance.m_ad_view != null)
m_instance.m_ad_view.setVisibility(View.INVISIBLE);
m_ad_view_visible = false;
if (m_ad_view != null)
m_ad_view.setVisibility(View.INVISIBLE);
}
});
}
public static void setDefaultOrientation() {
m_instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
public void setDefaultOrientation() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
public static void setLandScapeOrientation() {
m_instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
public void setLandScapeOrientation() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
public static void enableKeepScreenOn() {
m_instance.runOnUiThread(new Runnable() {
public void enableKeepScreenOn() {
runOnUiThread(new Runnable() {
public void run() {
m_instance.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}
public static void disableKeepScreenOn() {
m_instance.runOnUiThread(new Runnable() {
public void disableKeepScreenOn() {
runOnUiThread(new Runnable() {
public void run() {
m_instance.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}
public static Intent openFileDialog() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
return intent;
}
public static Intent createFileDialog(String filename) {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_TITLE, filename);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
return intent;
}
public static Intent openWebPage(String url) {
Intent intent = new Intent(m_instance, AuthView.class);
public Intent openWebPage(String url) {
Intent intent = new Intent(this, AuthView.class);
intent.putExtra("address", url);
return intent;
}
public static void closeWebPage(Intent i) {
if (m_auth_view != null) {
Intent intent = new Intent(m_instance, AuthView.class);
public void closeWebPage(Intent i) {
if (AuthView.m_current != null) {
Intent intent = new Intent(this, AuthView.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
m_auth_view.startActivity(intent);
m_auth_view.finish();
m_auth_view = null;
AuthView.m_current.startActivity(intent);
AuthView.m_current.finish();
AuthView.m_current = null;
}
}
public static Uri stringToUri(String uri) {
String basename = uri.substring(0, uri.lastIndexOf('/') + 1);
String filename = uri.substring(uri.lastIndexOf('/') + 1);
return Uri.parse(basename + Uri.encode(Uri.decode(filename)));
}
public static FileOutput openWrite(String uri) throws IOException {
FileOutput file = new FileOutput();
file.m_descriptor = m_instance.getContentResolver().
openFileDescriptor(stringToUri(uri), "w");
file.m_stream = new FileOutputStream(file.m_descriptor.getFileDescriptor());
return file;
public NotificationHelper notification() {
return m_notification_helper;
}
public static FileInput openRead(String uri) throws IOException {
FileInput file = new FileInput();
file.m_descriptor = m_instance.getContentResolver().
openFileDescriptor(stringToUri(uri), "r");
file.m_stream = new FileInputStream(file.m_descriptor.getFileDescriptor());
return file;
}
public static void write(FileOutput file, byte[] data) throws IOException {
file.m_stream.write(data);
}
public static byte[] read(FileInput file, int size) throws IOException {
byte[] buffer = new byte[size];
int nsize = file.m_stream.read(buffer);
if (nsize == -1)
return new byte[0];
byte[] result = new byte[nsize];
for (int i = 0; i < nsize; i++)
result[i] = buffer[i];
return result;
}
public static String filename(Uri uri) {
Cursor cursor = m_instance.getContentResolver().
public String filename(Uri uri) {
Cursor cursor = getContentResolver().
query(uri, null, null, null, null, null);
String result = "";
try {
......@@ -242,24 +171,4 @@ public class CloudBrowser extends QtActivity {
}
return result;
}
public static long size(FileInput file) throws IOException {
return file.m_descriptor.getStatSize();
}
public static boolean reset(FileInput file) throws IOException {
file.m_stream.close();
file.m_stream = new FileInputStream(file.m_descriptor.getFileDescriptor());
return true;
}
public static void closeWrite(FileOutput file) throws IOException {
file.m_stream.close();
file.m_descriptor.close();
}
public static void closeRead(FileInput file) throws IOException {
file.m_stream.close();
file.m_descriptor.close();
}
}
package org.videolan.cloudbrowser;
import android.os.ParcelFileDescriptor;
import android.content.Context;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInput {
private ParcelFileDescriptor m_descriptor;
private FileInputStream m_stream;
public FileInput(Context context, String uri) throws IOException {
m_descriptor = context.getContentResolver().
openFileDescriptor(Utility.stringToUri(uri), "r");
m_stream = new FileInputStream(m_descriptor.getFileDescriptor());
}
public long size() throws IOException {
return m_descriptor.getStatSize();
}
public boolean reset() throws IOException {
m_stream.close();
m_stream = new FileInputStream(m_descriptor.getFileDescriptor());
return true;
}
public void close() throws IOException {
m_stream.close();
m_descriptor.close();
}
public byte[] read(int size) throws IOException {
byte[] buffer = new byte[size];
int nsize = m_stream.read(buffer);
if (nsize == -1)
return new byte[0];
byte[] result = new byte[nsize];
for (int i = 0; i < nsize; i++)
result[i] = buffer[i];
return result;
}
}
package org.videolan.cloudbrowser;
import android.os.ParcelFileDescriptor;
import android.content.Context;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutput {
private ParcelFileDescriptor m_descriptor;
private FileOutputStream m_stream;
public FileOutput(Context context, String uri) throws IOException {
m_descriptor = context.getContentResolver().
openFileDescriptor(Utility.stringToUri(uri), "w");
m_stream = new FileOutputStream(m_descriptor.getFileDescriptor());
}
public void write(byte[] data) throws IOException {
m_stream.write(data);
}
public void close() throws IOException {
m_stream.close();
m_descriptor.close();
}
}
......@@ -3,6 +3,7 @@ package org.videolan.cloudbrowser;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
......@@ -11,52 +12,59 @@ import android.graphics.BitmapFactory;
import android.os.Build;
public class NotificationHelper {
private static NotificationManager m_notification_manager;
private Context m_context;
private NotificationManager m_notification_manager;
private static final String ActionPlay = "PLAY";
private static final String ActionPause = "PAUSE";
private static final String ActionNext = "NEXT";
public static final int PlayerNotification = 1;
public static native void callback(String action);
private static class Receiver extends BroadcastReceiver {
public void onReceive(Context ctx, Intent intent) {
callback(intent.getAction());
}
}
public static void initialize() {
m_notification_manager = (NotificationManager)CloudBrowser.instance().
getSystemService(Context.NOTIFICATION_SERVICE);
public static native void callback(String action);
public NotificationHelper(Context context) {
m_context = context;
m_notification_manager =
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
final IntentFilter filter = new IntentFilter();
filter.addAction(ActionPlay);
filter.addAction(ActionPause);
filter.addAction(ActionNext);
CloudBrowser.instance().registerReceiver(new Receiver(), filter);
context.registerReceiver(new Receiver(), filter);
hidePlayerNotification();
CloudBrowser.instance().startService(
new Intent(CloudBrowser.instance(), NotificationService.class)
m_context.startService(
new Intent(context, NotificationService.class)
);
}
public static void release() {
public void release() {
hidePlayerNotification();
}
public static void showPlayerNotification(boolean playing, String icon,
String content_text, String title) {
final PendingIntent play_intent = PendingIntent.getBroadcast(CloudBrowser.instance(),
public void showPlayerNotification(
boolean playing,
String icon,
String content_text,
String title
) {
final PendingIntent play_intent = PendingIntent.getBroadcast(m_context,
0, new Intent(ActionPlay), PendingIntent.FLAG_UPDATE_CURRENT);
final PendingIntent pause_intent = PendingIntent.getBroadcast(CloudBrowser.instance(),
final PendingIntent pause_intent = PendingIntent.getBroadcast(m_context,
0, new Intent(ActionPause), PendingIntent.FLAG_UPDATE_CURRENT);
final PendingIntent next_intent = PendingIntent.getBroadcast(CloudBrowser.instance(),
final PendingIntent next_intent = PendingIntent.getBroadcast(m_context,
0, new Intent(ActionNext), PendingIntent.FLAG_UPDATE_CURRENT);
final Intent intent = new Intent(CloudBrowser.instance(), CloudBrowser.class);
final Intent intent = new Intent(m_context, CloudBrowser.class);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final PendingIntent content_intent = PendingIntent.getActivity(CloudBrowser.instance(),
final PendingIntent content_intent = PendingIntent.getActivity(m_context,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(CloudBrowser.instance());
Notification.Builder builder = new Notification.Builder(m_context);
builder.setSmallIcon(R.drawable.icon).
setOngoing(playing).
setContentText(content_text).
......@@ -70,10 +78,11 @@ public class NotificationHelper {
else
builder.addAction(R.drawable.pause, ActionPause, pause_intent);
builder.addAction(R.drawable.next, ActionNext, next_intent);
m_notification_manager.notify(PlayerNotification, builder.build());
}
public static void hidePlayerNotification() {
public void hidePlayerNotification() {
m_notification_manager.cancel(PlayerNotification);
}
}
package org.videolan.cloudbrowser;
import android.net.Uri;
import android.content.Intent;
public class Utility {
public static Uri stringToUri(String uri) {
String basename = uri.substring(0, uri.lastIndexOf('/') + 1);
String filename = uri.substring(uri.lastIndexOf('/') + 1);
return Uri.parse(basename + Uri.encode(Uri.decode(filename)));
}
public static Intent openFileDialog() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
return intent;
}
public static Intent createFileDialog(String filename) {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_TITLE, filename);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
return intent;
}
}
......@@ -40,29 +40,24 @@ QString AndroidUtility::name() const { return "android"; }
bool AndroidUtility::openWebPage(QString url) {
if (intent_.isValid()) closeWebPage();
intent_ = QAndroidJniObject::callStaticObjectMethod(
"org/videolan/cloudbrowser/CloudBrowser", "openWebPage",
"(Ljava/lang/String;)Landroid/content/Intent;",
intent_ = QtAndroid::androidActivity().callObjectMethod(
"openWebPage", "(Ljava/lang/String;)Landroid/content/Intent;",
QAndroidJniObject::fromString(url).object());
QtAndroid::startActivity(intent_, RECEIVER_CODE, &receiver_);
return true;
}
void AndroidUtility::closeWebPage() {
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/CloudBrowser", "closeWebPage",
"(Landroid/content/Intent;)V", intent_.object());
QtAndroid::androidActivity().callMethod<void>(
"closeWebPage", "(Landroid/content/Intent;)V", intent_.object());
}
void AndroidUtility::landscapeOrientation() {
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/CloudBrowser", "setLandScapeOrientation",
"()V");
QtAndroid::androidActivity().callMethod<void>("setLandScapeOrientation");
}
void AndroidUtility::defaultOrientation() {
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/CloudBrowser", "setDefaultOrientation", "()V");
QtAndroid::androidActivity().callMethod<void>("setDefaultOrientation");
}
void AndroidUtility::showPlayerNotification(bool playing, QString filename,
......@@ -71,36 +66,34 @@ void AndroidUtility::showPlayerNotification(bool playing, QString filename,
GetThumbnailRequest::thumbnail_path(filename));
auto arg1 = QAndroidJniObject::fromString(filename);
auto arg2 = QAndroidJniObject::fromString(title);
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/NotificationHelper", "showPlayerNotification",
auto notification = QtAndroid::androidContext().callObjectMethod(
"notification", "()Lorg/videolan/cloudbrowser/NotificationHelper;");
notification.callMethod<void>(
"showPlayerNotification",
"(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", playing,
arg0.object(), arg1.object(), arg2.object());
}
void AndroidUtility::hidePlayerNotification() {
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/NotificationHelper", "hidePlayerNotification",
"()V");
auto notification = QtAndroid::androidContext().callObjectMethod(
"notification", "()Lorg/videolan/cloudbrowser/NotificationHelper;");
notification.callMethod<void>("hidePlayerNotification");
}
void AndroidUtility::enableKeepScreenOn() {
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/CloudBrowser", "enableKeepScreenOn", "()V");
QtAndroid::androidActivity().callMethod<void>("enableKeepScreenOn");
}
void AndroidUtility::disableKeepScreenOn() {
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/CloudBrowser", "disableKeepScreenOn", "()V");
QtAndroid::androidActivity().callMethod<void>("disableKeepScreenOn");
}
void AndroidUtility::showAd() {
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/CloudBrowser", "showAd", "()V");
QtAndroid::androidActivity().callMethod<void>("showAd");
}
void AndroidUtility::hideAd() {
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/CloudBrowser", "hideAd", "()V");
QtAndroid::androidActivity().callMethod<void>("hideAd");
}
void AndroidUtility::ResultReceiver::handleActivityResult(
......
......@@ -5,17 +5,17 @@
#ifdef __ANDROID__
#include <QAndroidJniEnvironment>
#include <QtAndroid>
AndroidFile::AndroidFile(QString uri) : uri_(uri) {}
bool AndroidFile::open(QIODevice::OpenMode mode) {
QAndroidJniEnvironment env;
if (mode == QIODevice::WriteOnly) {
file_ = QAndroidJniObject::callStaticObjectMethod(
"org/videolan/cloudbrowser/CloudBrowser", "openWrite",
"(Ljava/lang/String;)Lorg/videolan/cloudbrowser/"
"CloudBrowser$FileOutput;",
QAndroidJniObject::fromString(uri_).object());
file_ = QAndroidJniObject("org/videolan/cloudbrowser/FileOutput",
"(Landroid/content/Context;Ljava/lang/String;)V",
QtAndroid::androidActivity().object(),
QAndroidJniObject::fromString(uri_).object());
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
......@@ -24,11 +24,10 @@ bool AndroidFile::open(QIODevice::OpenMode mode) {
setOpenMode(mode);
return true;
} else if (mode == QIODevice::ReadOnly) {
file_ = QAndroidJniObject::callStaticObjectMethod(
"org/videolan/cloudbrowser/CloudBrowser", "openRead",
"(Ljava/lang/String;)Lorg/videolan/cloudbrowser/"
"CloudBrowser$FileInput;",
QAndroidJniObject::fromString(uri_).object());
file_ = QAndroidJniObject("org/videolan/cloudbrowser/FileInput",
"(Landroid/content/Context;Ljava/lang/String;)V",
QtAndroid::androidActivity().object(),
QAndroidJniObject::fromString(uri_).object());
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
......@@ -42,25 +41,13 @@ bool AndroidFile::open(QIODevice::OpenMode mode) {
void AndroidFile::close() {
if (!isOpen()) return;
if (openMode() == QIODevice::WriteOnly)
QAndroidJniObject::callStaticMethod<void>(
"org/videolan/cloudbrowser/CloudBrowser", "closeWrite",
"(Lorg/videolan/cloudbrowser/CloudBrowser$FileOutput;)V",