{"id":79,"date":"2023-07-02T12:10:15","date_gmt":"2023-07-02T12:10:15","guid":{"rendered":"https:\/\/blogs.scummvm.org\/ankushdutt\/?p=79"},"modified":"2023-07-02T14:28:26","modified_gmt":"2023-07-02T14:28:26","slug":"playstore-dlc","status":"publish","type":"post","link":"https:\/\/blogs.scummvm.org\/ankushdutt\/2023\/07\/02\/playstore-dlc\/","title":{"rendered":"DLC Manager for Android Play Store"},"content":{"rendered":"<p>This week I started extending DLC Manager to support Play Store.<\/p>\n<p>For handling the downloading of on-demand games, Google has provided two SDKs &#8211; one for native (C\/C++) and another one for Java\/Kotlin.<\/p>\n<p>At first, I was going with native play asset SDK. This SDK consists of some header files (like <code>asset_pack.h<\/code>), a <code>.cmake<\/code> file, and shared (<code>.so<\/code>) and static (<code>.a<\/code>) libraries. The <code>.cmake<\/code> file has helper functions that add shared\/static libraries to the project. Using native play asset SDK caused me some troubles &#8211; it required us to include these SDK-specific includes in our build system, which might not be an easy task. However, the major reason I had to switch to using Java SDK was &#8211; developers will need to download manually and set up the native SDK. I could probably add the complete SDK itself in our ScummVM repository to save some setup time, but that will be around 400 MB.<\/p>\n<p>So, we decided to take the &#8220;easy and maintainable&#8221; approach &#8211; Just use the Play Asset SDK for Java. There&#8217;s no need to manually download the SDK, and we only require to add a new dependency (<code>com.google.android.play:asset-delivery:2.1.0<\/code>) in our Android&#8217;s build.gradle. Then we can simply use all its functions (like <a href=\"https:\/\/developer.android.com\/reference\/com\/google\/android\/play\/core\/assetpacks\/AssetPackManager.html#fetch(java.util.List%3Cjava.lang.String%3E)\">fetch()<\/a> that requests download) in java. However, it is not that easy since we need to call these functions from C++.<\/p>\n<p>That&#8217;s where JNI (Java Native Interface) comes into play. It acts as a bridge between Java code and Native (C\/C++) code. Using JNI, we can call any method of an object implemented in Java from C++ or vice versa.<\/p>\n<p>Currently, in Java, I am creating a new <a href=\"https:\/\/developer.android.com\/reference\/com\/google\/android\/play\/core\/assetpacks\/AssetPackManager.html\">AssetPackManager&#8217;s<\/a> object using <a href=\"https:\/\/developer.android.com\/reference\/com\/google\/android\/play\/core\/assetpacks\/AssetPackManagerFactory\">AssetPackManagerFactory&#8217;s<\/a> getInstance() static method, and from C++, I am trying to call its function using JNI and getting its response. The response would be a <code>jobject<\/code> type. Initially, I thought I could handle this returned <code>jobject<\/code> in my C++ code (i.e. manipulate it to return the C++ function&#8217;s expected return type) but it seems to be difficult. Lephilousophe suggested me to handle those DLC-related functions on Java side first. So, I would have a simple API that I can call from C++ that can return something simple (like <code>String<\/code>) instead of\u00a0 something complex (like <code>AssetPackLocation<\/code>).<\/p>\n<p>As a side note, there was also some problem with my code that made builds on Mac and Windows fail. I was also able to fix it. But I still need to fix my commit history for failing builds.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This week I started extending DLC Manager to support Play Store. For handling the downloading of on-demand games, Google has provided two SDKs &#8211; one for native (C\/C++) and another one for Java\/Kotlin. At first, I was going with native play asset SDK. This SDK consists of some header files (like asset_pack.h), a .cmake file, [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-79","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/posts\/79","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/comments?post=79"}],"version-history":[{"count":6,"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/posts\/79\/revisions"}],"predecessor-version":[{"id":85,"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/posts\/79\/revisions\/85"}],"wp:attachment":[{"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/media?parent=79"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/categories?post=79"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/ankushdutt\/wp-json\/wp\/v2\/tags?post=79"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}