Skip to content
Snippets Groups Projects
Commit d5ca4829 authored by Geoffrey Métais's avatar Geoffrey Métais
Browse files

Extensions discovery and listing from VLC App

parent 7e34356e
No related branches found
No related tags found
No related merge requests found
......@@ -3,7 +3,8 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/scrollable_group"
android:checkableBehavior="single">
android:checkableBehavior="single"
android:orderInCategory="1">
<item
android:id="@+id/nav_video"
android:title="@string/video"
......@@ -36,7 +37,8 @@
android:icon="@drawable/ic_menu_history" />
</group>
<group android:id="@+id/fixed_group"
android:checkableBehavior="single">
android:checkableBehavior="single"
android:orderInCategory="3">
<item
android:id="@+id/nav_settings"
android:title="@string/preferences"
......
......@@ -545,6 +545,7 @@
<item>YV12</item>
</string-array>
<string name="chroma_format_default" translatable="false">RV32</string>
<string name="plugins">Plugins</string>
<string-array name="chroma_formats" translatable="false">
<item>RGB 32-bit</item>
......
......@@ -51,6 +51,7 @@ import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
......@@ -82,12 +83,15 @@ import org.videolan.vlc.interfaces.ISortable;
import org.videolan.vlc.media.MediaDatabase;
import org.videolan.vlc.media.MediaLibrary;
import org.videolan.vlc.media.MediaUtils;
import org.videolan.vlc.plugin.ExtensionListing;
import org.videolan.vlc.plugin.PluginService;
import org.videolan.vlc.util.Permissions;
import org.videolan.vlc.util.Util;
import org.videolan.vlc.util.VLCInstance;
import org.videolan.vlc.util.WeakHandler;
import java.util.List;
public class MainActivity extends AudioPlayerContainerActivity implements SearchSuggestionsAdapter.SuggestionDisplay, FilterQueryProvider, NavigationView.OnNavigationItemSelectedListener {
public final static String TAG = "VLC/MainActivity";
......@@ -123,6 +127,10 @@ public class MainActivity extends AudioPlayerContainerActivity implements Search
Menu mMenu;
private SearchView mSearchView;
// Plugins management
private PluginService mPluginService;
private static final int PLUGIN_NAVIGATION_GROUP = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -211,6 +219,10 @@ public class MainActivity extends AudioPlayerContainerActivity implements Search
/* Reload the latest preferences */
reloadPreferences();
// Bind service which discoverves au connects toplugins
bindService(new Intent(MainActivity.this,
PluginService.class), mPluginServiceConnection, Context.BIND_AUTO_CREATE);
}
private void setupNavigationView() {
......@@ -260,30 +272,40 @@ public class MainActivity extends AudioPlayerContainerActivity implements Search
mActionBar.setHomeButtonEnabled(true);
}
@Override
protected void onStart() {
super.onStart();
// Log.d("VLC/PluginService", "binding service");
// startService(new Intent(this, PluginService.class));
boolean connected = bindService(new Intent(MainActivity.this,
PluginService.class), mConnection, Context.BIND_AUTO_CREATE);
Log.d("VLC/PluginService", "binding service "+connected);
}
@Override
protected void onStop() {
super.onStop();
unbindService(mConnection);
unbindService(mPluginServiceConnection);
}
private void loadPlugins() {
List<ExtensionListing> plugins = mPluginService.getAvailableExtensions();
if (plugins.isEmpty()) {
unbindService(mPluginServiceConnection);
mPluginService.stopSelf();
return;
}
PackageManager pm = getPackageManager();
Menu navMenu = mNavigationView.getMenu();
SubMenu subMenu = navMenu.addSubMenu(PLUGIN_NAVIGATION_GROUP, PLUGIN_NAVIGATION_GROUP,
PLUGIN_NAVIGATION_GROUP, R.string.plugins);
for (int i = 0 ; i < plugins.size() ; ++i) {
MenuItem item = subMenu.add(PLUGIN_NAVIGATION_GROUP, i, 0, plugins.get(i).title());
try {
item.setIcon(pm.getApplicationIcon(plugins.get(i).componentName().getPackageName()));
} catch (PackageManager.NameNotFoundException e) {
item.setIcon(R.drawable.icon);
}
}
}
private PluginService mBoundService;
private ServiceConnection mConnection = new ServiceConnection() {
private ServiceConnection mPluginServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("VLC/PluginService", "onServiceConnected");
mBoundService = ((PluginService.LocalBinder)service).getService();
mPluginService = ((PluginService.LocalBinder)service).getService();
loadPlugins();
}
@Override
......@@ -840,38 +862,42 @@ public class MainActivity extends AudioPlayerContainerActivity implements Search
if(item == null)
return false;
String tag = getTag(id);
switch (id){
case R.id.nav_about:
showSecondaryFragment(SecondaryActivity.ABOUT);
break;
case R.id.nav_settings:
startActivityForResult(new Intent(this, PreferencesActivity.class), ACTIVITY_RESULT_PREFERENCES);
break;
case R.id.nav_directories:
if (TextUtils.equals(BuildConfig.FLAVOR_target, "chrome")) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("audio/* video/*");
startActivityForResult(intent, ACTIVITY_RESULT_OPEN);
mDrawerLayout.closeDrawer(mNavigationView);
return true;
}
default:
if (item.getGroupId() == PLUGIN_NAVIGATION_GROUP) {
mPluginService.connectService(id);
} else {
String tag = getTag(id);
switch (id){
case R.id.nav_about:
showSecondaryFragment(SecondaryActivity.ABOUT);
break;
case R.id.nav_settings:
startActivityForResult(new Intent(this, PreferencesActivity.class), ACTIVITY_RESULT_PREFERENCES);
break;
case R.id.nav_directories:
if (TextUtils.equals(BuildConfig.FLAVOR_target, "chrome")) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("audio/* video/*");
startActivityForResult(intent, ACTIVITY_RESULT_OPEN);
mDrawerLayout.closeDrawer(mNavigationView);
return true;
}
default:
/* Slide down the audio player */
slideDownAudioPlayer();
slideDownAudioPlayer();
/* Switch the fragment */
Fragment fragment = getFragment(id);
if (fragment instanceof MediaBrowserFragment)
((MediaBrowserFragment)fragment).setReadyToDisplay(false);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_placeholder, fragment, tag);
ft.addToBackStack(getTag(mCurrentFragment));
ft.commit();
mCurrentFragment = id;
if (mFocusedPrior != 0)
requestFocusOnSearch();
Fragment fragment = getFragment(id);
if (fragment instanceof MediaBrowserFragment)
((MediaBrowserFragment)fragment).setReadyToDisplay(false);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_placeholder, fragment, tag);
ft.addToBackStack(getTag(mCurrentFragment));
ft.commit();
mCurrentFragment = id;
if (mFocusedPrior != 0)
requestFocusOnSearch();
}
}
mDrawerLayout.closeDrawer(mNavigationView);
mNavigationView.setCheckedItem(mCurrentFragment);
......
......@@ -40,6 +40,8 @@ public class ExtensionListing implements Parcelable {
private int mIcon;
private ComponentName mSettingsActivity;
private PluginService.Connection connection;
public ExtensionListing(){}
@Override
......@@ -177,6 +179,14 @@ public class ExtensionListing implements Parcelable {
return this;
}
public PluginService.Connection getConnection() {
return connection;
}
public void setConnection(PluginService.Connection connection) {
this.connection = connection;
}
/**
* @see android.os.Parcelable
*/
......
......@@ -49,6 +49,7 @@ import org.videolan.vlc.plugin.api.IExtensionHost;
import org.videolan.vlc.plugin.api.IExtensionService;
import org.videolan.vlc.plugin.api.VLCExtensionItem;
import java.util.LinkedList;
import java.util.List;
public class PluginService extends Service {
......@@ -88,7 +89,7 @@ public class PluginService extends Service {
}
}
public List<String> getAvailableExtensions() {
public List<ExtensionListing> getAvailableExtensions() {
PackageManager pm = VLCApplication.getAppContext().getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentServices(
new Intent(ACTION_EXTENSION), PackageManager.GET_META_DATA);
......@@ -108,21 +109,29 @@ public class PluginService extends Service {
info.settingsActivity(ComponentName.unflattenFromString(
resolveInfo.serviceInfo.packageName + "/" + settingsActivity));
}
mPlugins.add(info);
}
info.icon(resolveInfo.getIconResource());
//availableExtensions.add(info); TODO
Log.d(TAG, "componentName "+info.componentName().toString());
Log.d(TAG, " - title "+info.title());
Log.d(TAG, " - protocolVersion "+info.protocolVersion());
Log.d(TAG, " - settingsActivity "+info.settingsActivity());
Log.d(TAG, " - settingsActivity " + info.settingsActivity());
connectService(info);
// connectService(info);
}
return null;
return plugins;
}
private void connectService(ExtensionListing info) {
private List<ExtensionListing> mPlugins = new LinkedList<>();
int mCurrentIndex = -1;
public void connectService(int index) {
ExtensionListing info = mPlugins.get(index);
if (mCurrentIndex != -1) {
disconnect();
}
final Connection conn = new Connection();
ComponentName cn = info.componentName();
conn.componentName = cn;
......@@ -142,22 +151,32 @@ public class PluginService extends Service {
@Override
public void onServiceDisconnected(ComponentName name) {
unbindService(conn.serviceConnection);
}
};
info.setConnection(conn);
try {
if (!bindService(new Intent().setComponent(cn), conn.serviceConnection,
Context.BIND_AUTO_CREATE)) {
Log.e(TAG, "Error binding to extension " + cn.flattenToShortString());
info.setConnection(null);
// return null;
}
} catch (SecurityException e) {
Log.e(TAG, "Error binding to extension " + cn.flattenToShortString(), e);
info.setConnection(null);
// return null;
}
}
private void disconnect() {
ExtensionListing plugin = mPlugins.get(mCurrentIndex);
Connection conn = plugin.getConnection();
if (conn != null)
unbindService(conn.serviceConnection);
plugin.setConnection(null);
}
private IExtensionHost makeHostInterface(Connection conn) {
return new IExtensionHost.Stub(){
......@@ -177,7 +196,7 @@ public class PluginService extends Service {
};
}
private static class Connection {
public static class Connection {
boolean ready = false;
ComponentName componentName;
ServiceConnection serviceConnection;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment