[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / platform / android / filesystem / AndroidAppFile.cpp
blob9f3ccfecae42edf4fec6a4c1ce566f601241ead7
1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "AndroidAppFile.h"
11 #include "URL.h"
12 #include "Util.h"
13 #include "utils/URIUtils.h"
14 #include "utils/log.h"
16 #include "platform/android/activity/XBMCApp.h"
18 #include <android/bitmap.h>
19 #include <androidjni/Bitmap.h>
20 #include <androidjni/BitmapDrawable.h>
21 #include <androidjni/Build.h>
22 #include <androidjni/Canvas.h>
23 #include <androidjni/Context.h>
24 #include <androidjni/DisplayMetrics.h>
25 #include <androidjni/Drawable.h>
26 #include <androidjni/PackageManager.h>
27 #include <androidjni/Resources.h>
28 #include <jni.h>
29 #include <sys/stat.h>
30 using namespace XFILE;
32 CFileAndroidApp::CFileAndroidApp(void)
34 m_iconWidth = 0;
35 m_iconHeight = 0;
38 CFileAndroidApp::~CFileAndroidApp(void)
40 Close();
43 bool CFileAndroidApp::Open(const CURL& url)
45 m_url = url;
46 m_packageName = URIUtils::GetFileName(url.Get());
47 m_packageName = m_packageName.substr(0, m_packageName.size() - 4);
49 const std::vector<androidPackage> applications = CXBMCApp::Get().GetApplications();
50 for (const auto& i : applications)
52 if (i.packageName == m_packageName)
54 m_packageLabel = i.packageLabel;
55 m_icon = i.icon;
56 return true;
60 return false;
63 bool CFileAndroidApp::Exists(const CURL& url)
65 std::string appname = URIUtils::GetFileName(url.Get());
66 appname = appname.substr(0, appname.size() - 4);
68 const std::vector<androidPackage> applications = CXBMCApp::Get().GetApplications();
69 for (const auto& i : applications)
71 if (i.packageName == appname)
72 return true;
75 return false;
78 namespace
81 CJNIBitmap GetBitmapFromDrawable(CJNIDrawable& drawable)
83 CJNIBitmap bmp = CJNIBitmap::createBitmap(drawable.getIntrinsicWidth(),
84 drawable.getIntrinsicHeight(), CJNIBitmap::ARGB_8888);
85 CJNICanvas canvas(bmp);
87 drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
88 drawable.draw(canvas);
90 return bmp;
93 } // namespace
95 unsigned int CFileAndroidApp::ReadIcon(unsigned char** lpBuf, unsigned int* width, unsigned int* height)
97 JNIEnv* env = xbmc_jnienv();
98 void *bitmapBuf = NULL;
99 int densities[] = { CJNIDisplayMetrics::DENSITY_XXXHIGH, CJNIDisplayMetrics::DENSITY_XXHIGH, CJNIDisplayMetrics::DENSITY_XHIGH, -1 };
101 CJNIBitmap bmp;
102 jclass cBmpDrw = env->FindClass("android/graphics/drawable/BitmapDrawable");
103 jclass cAidDrw = CJNIBase::GetSDKVersion() >= 26
104 ? env->FindClass("android/graphics/drawable/AdaptiveIconDrawable")
105 : nullptr;
107 if (m_icon)
109 CJNIResources res = CJNIContext::GetPackageManager().getResourcesForApplication(m_packageName);
110 if (res)
112 for (int i=0; densities[i] != -1 && !bmp; ++i)
114 int density = densities[i];
115 CJNIDrawable drw = res.getDrawableForDensity(m_icon, density);
116 if (xbmc_jnienv()->ExceptionCheck())
117 xbmc_jnienv()->ExceptionClear();
118 else if (!drw);
119 else
121 if (env->IsInstanceOf(drw.get_raw(), cBmpDrw))
123 CJNIBitmapDrawable resbmp = drw;
124 if (resbmp)
125 bmp = resbmp.getBitmap();
127 else if (cAidDrw && env->IsInstanceOf(drw.get_raw(), cAidDrw))
129 bmp = GetBitmapFromDrawable(drw);
136 if (!bmp)
138 CJNIDrawable drw = CJNIContext::GetPackageManager().getApplicationIcon(m_packageName);
139 if (xbmc_jnienv()->ExceptionCheck())
140 xbmc_jnienv()->ExceptionClear();
141 else if (!drw);
142 else
144 if (env->IsInstanceOf(drw.get_raw(), cBmpDrw))
146 CJNIBitmapDrawable resbmp = drw;
147 if (resbmp)
148 bmp = resbmp.getBitmap();
150 else if (cAidDrw && env->IsInstanceOf(drw.get_raw(), cAidDrw))
152 bmp = GetBitmapFromDrawable(drw);
156 if (!bmp)
157 return 0;
159 AndroidBitmapInfo info;
160 AndroidBitmap_getInfo(env, bmp.get_raw(), &info);
162 if (!info.width || !info.height)
163 return 0;
165 if (info.stride != info.width * 4)
167 CLog::Log(LOGWARNING, "CFileAndroidApp::ReadIcon: Unsupported icon format {}", info.format);
168 return 0;
171 AndroidBitmap_lockPixels(env, bmp.get_raw(), &bitmapBuf);
172 if (bitmapBuf)
174 const int imgsize = info.width * info.height * 4;
175 *lpBuf = new unsigned char[imgsize];
176 *width = info.width;
177 *height = info.height;
179 memcpy(*lpBuf, bitmapBuf, imgsize);
180 AndroidBitmap_unlockPixels(env, bmp.get_raw());
182 return imgsize;
184 return 0;
187 void CFileAndroidApp::Close()
191 int CFileAndroidApp::GetChunkSize()
193 return 0;
195 int CFileAndroidApp::Stat(const CURL& url, struct __stat64* buffer)
197 return 0;
199 int CFileAndroidApp::IoControl(EIoControl request, void* param)
201 if(request == IOCTRL_SEEK_POSSIBLE)
202 return 0;
203 return 1;