From da65ea209e4454454ae2d58b83bfb49e0aa1145c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20T=C3=BCrkoglu?= Date: Sat, 2 Nov 2013 23:36:08 +0100 Subject: [PATCH 1/2] Fix NPE when "Pictures" section is empty Currently we only check for jsonShares' being null and return if that is the case. Shares object might not be null but the sources node might be. Verify it's not null before continuing. --- src/org/xbmc/jsonrpc/client/InfoClient.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/org/xbmc/jsonrpc/client/InfoClient.java b/src/org/xbmc/jsonrpc/client/InfoClient.java index bbcb0557..594dbb55 100644 --- a/src/org/xbmc/jsonrpc/client/InfoClient.java +++ b/src/org/xbmc/jsonrpc/client/InfoClient.java @@ -74,11 +74,9 @@ public ArrayList getDirectory(INotifiableManager manager, String p * @return */ public ArrayList getShares(INotifiableManager manager, int mediaType) { - - final ArrayList shares = new ArrayList(); final JsonNode jsonShares = mConnection.getJson(manager, "Files.GetSources", obj().p("media", MediaType.getName(mediaType))); - if(jsonShares != null){ + if(jsonShares != null && jsonShares.get("sources") != null) { for (Iterator i = jsonShares.get("sources").getElements(); i.hasNext();) { JsonNode jsonShare = (JsonNode)i.next(); shares.add(new FileLocation(getString(jsonShare, "label"), getString(jsonShare, "file"))); From 46fd9f0a44af04ab5d5c6442df96a05bc52aa874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20T=C3=BCrkoglu?= Date: Sun, 3 Nov 2013 02:19:32 +0100 Subject: [PATCH 2/2] Fix "Shutdown" not working Shutdown uses the EventServer and this brings up the shutdown dialog where you need to choose what to do. This behaviour is not inline with what we experience on iOS client and makes it hard to shut down a system from remote as the selection might end up in dialog close or the first item. Convert the call to JSON-RPC instead. This will gracefully shutdown the XBMC server and power off the system. --- .../android/remote/business/ControlManager.java | 14 ++++++++++++++ .../presentation/controller/HomeController.java | 8 +++++--- src/org/xbmc/android/util/PowerDown.java | 15 +++++++++------ src/org/xbmc/api/business/IControlManager.java | 9 ++++++++- src/org/xbmc/api/data/IControlClient.java | 9 ++++++++- src/org/xbmc/httpapi/client/ControlClient.java | 11 ++++++++++- src/org/xbmc/jsonrpc/client/ControlClient.java | 9 +++++++++ 7 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/org/xbmc/android/remote/business/ControlManager.java b/src/org/xbmc/android/remote/business/ControlManager.java index 7f0f265f..ad60db28 100644 --- a/src/org/xbmc/android/remote/business/ControlManager.java +++ b/src/org/xbmc/android/remote/business/ControlManager.java @@ -302,4 +302,18 @@ public void doRun() throws Exception { } }); } + + /** + * Powers off the system. + * @param response Response object + * @param context Context reference + */ + public void powerOff(final DataResponse response, final Context context) { + mHandler.post(new Command(response, this) { + @Override + public void doRun() throws Exception { + response.value = control(context).powerOff(ControlManager.this); + } + }); + } } \ No newline at end of file diff --git a/src/org/xbmc/android/remote/presentation/controller/HomeController.java b/src/org/xbmc/android/remote/presentation/controller/HomeController.java index 7b683d03..3c4f13e2 100644 --- a/src/org/xbmc/android/remote/presentation/controller/HomeController.java +++ b/src/org/xbmc/android/remote/presentation/controller/HomeController.java @@ -46,6 +46,7 @@ import org.xbmc.android.util.WakeOnLan; import org.xbmc.android.util.WifiHelper; import org.xbmc.api.business.DataResponse; +import org.xbmc.api.business.IControlManager; import org.xbmc.api.business.IInfoManager; import org.xbmc.api.business.IMusicManager; import org.xbmc.api.business.INotifiableManager; @@ -83,17 +84,17 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.WindowManager; -import android.view.View.OnClickListener; import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.GridView; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; -import android.widget.AdapterView.OnItemClickListener; public class HomeController extends AbstractController implements INotifiableController, IController, Observer, OnSharedPreferenceChangeListener { @@ -317,7 +318,8 @@ public void onItemClick(AdapterView listView, View v, int position, long ID) } break; case HOME_ACTION_POWERDOWN: - PowerDown powerdown = new PowerDown(); + final IControlManager cm = ManagerFactory.getControlManager(HomeController.this); + PowerDown powerdown = new PowerDown(cm); powerdown.ShowDialog(mActivity); break; } diff --git a/src/org/xbmc/android/util/PowerDown.java b/src/org/xbmc/android/util/PowerDown.java index 234af4bc..3e6ee3f9 100644 --- a/src/org/xbmc/android/util/PowerDown.java +++ b/src/org/xbmc/android/util/PowerDown.java @@ -21,9 +21,9 @@ package org.xbmc.android.util; -import org.xbmc.android.remote.business.EventClientManager; +import org.xbmc.api.business.DataResponse; +import org.xbmc.api.business.IControlManager; import org.xbmc.api.business.IEventClientManager; -import org.xbmc.eventclient.ButtonCodes; import android.app.Activity; import android.app.AlertDialog; @@ -32,8 +32,13 @@ public class PowerDown { IEventClientManager mEventClientManager; private Activity mActivity; + private final IControlManager cm; - public void ShowDialog(Activity activity) { + public PowerDown(IControlManager cm) { + this.cm = cm; + } + + public void ShowDialog(final Activity activity) { mActivity = activity; AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); builder.setMessage("Are you sure you want to power off?").setCancelable(false); @@ -44,9 +49,7 @@ public void onClick(DialogInterface dialog, int id) { } private void Down() { - EventClientManager pdEventClientManager = new EventClientManager(); - pdEventClientManager.sendButton("R1", ButtonCodes.REMOTE_POWER, false, true, true, (short) 0, (byte) 0); - + cm.powerOff(new DataResponse(), activity.getApplicationContext()); } }).setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { diff --git a/src/org/xbmc/api/business/IControlManager.java b/src/org/xbmc/api/business/IControlManager.java index 5d1070eb..c89e74c1 100644 --- a/src/org/xbmc/api/business/IControlManager.java +++ b/src/org/xbmc/api/business/IControlManager.java @@ -180,4 +180,11 @@ public void setGuiSetting(final DataResponse response, final int settin * @return true on success, false otherwise. */ public void sendText(final DataResponse response, final String text, final Context context); -} \ No newline at end of file + + /** + * Powers off the system. + * @param response Response object + * @param context Context reference + */ + public void powerOff(final DataResponse response, final Context context); +} diff --git a/src/org/xbmc/api/data/IControlClient.java b/src/org/xbmc/api/data/IControlClient.java index 37152b74..b0dfa737 100644 --- a/src/org/xbmc/api/data/IControlClient.java +++ b/src/org/xbmc/api/data/IControlClient.java @@ -75,6 +75,13 @@ public interface IControlClient extends IClient { public boolean pause(INotifiableManager manager); /** + * Powers off the system. + * @param manager Manager reference + * @return true on success, false otherwise. + */ + public boolean powerOff(INotifiableManager manager); + + /** * Stops the currently playing media. * @param manager Manager reference * @return true on success, false otherwise. @@ -101,7 +108,7 @@ public interface IControlClient extends IClient { * Seeks to a position. If type is *
    *
  • absolute - Sets the playing position of the currently - * playing media as a percentage of the media�s length.
  • + * playing media as a percentage of the media's length. *
  • relative - Adds/Subtracts the current percentage on to * the current position in the song
  • *
diff --git a/src/org/xbmc/httpapi/client/ControlClient.java b/src/org/xbmc/httpapi/client/ControlClient.java index 42f1c0ab..45851006 100644 --- a/src/org/xbmc/httpapi/client/ControlClient.java +++ b/src/org/xbmc/httpapi/client/ControlClient.java @@ -175,7 +175,7 @@ public boolean setVolume(INotifiableManager manager, int volume) { * Seeks to a position. If type is *
    *
  • absolute - Sets the playing position of the currently - * playing media as a percentage of the media�s length.
  • + * playing media as a percentage of the media's length. *
  • relative - Adds/Subtracts the current percentage on to * the current position in the song
  • *
@@ -479,4 +479,13 @@ else if (map.get("Type").contains("Video")) { } } } + + /** + * Powers off the system. + * @param response Response object + * @return true on success, false otherwise. + */ + public boolean powerOff(INotifiableManager manager) { + return mConnection.getBoolean(manager, "Shutdown()"); + } } diff --git a/src/org/xbmc/jsonrpc/client/ControlClient.java b/src/org/xbmc/jsonrpc/client/ControlClient.java index 68cf3f98..82ed0935 100644 --- a/src/org/xbmc/jsonrpc/client/ControlClient.java +++ b/src/org/xbmc/jsonrpc/client/ControlClient.java @@ -125,6 +125,15 @@ public boolean stop(INotifiableManager manager) { return mConnection.getString(manager, "Player.Stop", obj().p("playerid", getActivePlayerId(manager))).equals("OK"); } + /** + * Powers off the system. + * @param manager Manager reference + * @return OK on success, false otherwise. + */ + public boolean powerOff(INotifiableManager manager) { + return mConnection.getString(manager, "System.Shutdown", null).equals("OK"); + } + /** * Start playing the media file at the given URL * @param manager Manager reference