mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 06:03:15 +08:00
4 digit library version numeration implemented in OpenCV Manager
Code refactoring done. OpenCV library version type changed to int. Some UI labels updated. OpenCV Manager verison incremented.
This commit is contained in:
parent
101e9bd456
commit
4feae810fa
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.engine"
|
||||
android:versionCode="24@ANDROID_PLATFORM_VERSION_CODE@"
|
||||
android:versionName="2.4" >
|
||||
android:versionCode="25@ANDROID_PLATFORM_VERSION_CODE@"
|
||||
android:versionName="2.5" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" />
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
|
||||
|
@ -15,60 +15,44 @@ using namespace android;
|
||||
|
||||
const int OpenCVEngine::Platform = DetectKnownPlatforms();
|
||||
const int OpenCVEngine::CpuID = GetCpuID();
|
||||
const int OpenCVEngine::KnownVersions[] = {2040000, 2040100, 2040200, 2040300, 2040301, 2040302};
|
||||
|
||||
std::set<std::string> OpenCVEngine::InitKnownOpenCVersions()
|
||||
bool OpenCVEngine::ValidateVersion(int version)
|
||||
{
|
||||
std::set<std::string> result;
|
||||
for (size_t i = 0; i < sizeof(KnownVersions)/sizeof(int); i++)
|
||||
if (KnownVersions[i] == version)
|
||||
return true;
|
||||
|
||||
result.insert("240");
|
||||
result.insert("241");
|
||||
result.insert("242");
|
||||
result.insert("243");
|
||||
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::set<std::string> OpenCVEngine::KnownVersions = InitKnownOpenCVersions();
|
||||
|
||||
bool OpenCVEngine::ValidateVersionString(const std::string& version)
|
||||
int OpenCVEngine::NormalizeVersionString(std::string version)
|
||||
{
|
||||
return (KnownVersions.find(version) != KnownVersions.end());
|
||||
}
|
||||
|
||||
std::string OpenCVEngine::NormalizeVersionString(std::string version)
|
||||
{
|
||||
std::string result = "";
|
||||
std::string suffix = "";
|
||||
int result = 0;
|
||||
|
||||
if (version.empty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (('a' == version[version.size()-1]) || ('b' == version[version.size()-1]))
|
||||
{
|
||||
suffix = version[version.size()-1];
|
||||
version.erase(version.size()-1);
|
||||
}
|
||||
|
||||
std::vector<std::string> parts = SplitStringVector(version, '.');
|
||||
|
||||
if (parts.size() >= 2)
|
||||
// Use only 4 digits of the version, i.e. 1.2.3.4.
|
||||
// Other digits will be ignored.
|
||||
if (parts.size() > 4)
|
||||
parts.erase(parts.begin()+4, parts.end());
|
||||
|
||||
int multiplyer = 1000000;
|
||||
for (std::vector<std::string>::const_iterator it = parts.begin(); it != parts.end(); ++it)
|
||||
{
|
||||
if (parts.size() >= 3)
|
||||
{
|
||||
result = parts[0] + parts[1] + parts[2] + suffix;
|
||||
if (!ValidateVersionString(result))
|
||||
result = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = parts[0] + parts[1] + "0" + suffix;
|
||||
if (!ValidateVersionString(result))
|
||||
result = "";
|
||||
}
|
||||
int digit = atoi(it->c_str());
|
||||
result += multiplyer*digit;
|
||||
multiplyer /= 100;
|
||||
}
|
||||
|
||||
if (!ValidateVersion(result))
|
||||
result = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -86,19 +70,19 @@ int32_t OpenCVEngine::GetVersion()
|
||||
String16 OpenCVEngine::GetLibPathByVersion(android::String16 version)
|
||||
{
|
||||
std::string std_version(String8(version).string());
|
||||
std::string norm_version;
|
||||
int norm_version;
|
||||
std::string path;
|
||||
|
||||
LOGD("OpenCVEngine::GetLibPathByVersion(%s) impl", String8(version).string());
|
||||
|
||||
norm_version = NormalizeVersionString(std_version);
|
||||
|
||||
if (!norm_version.empty())
|
||||
if (0 != norm_version)
|
||||
{
|
||||
path = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID);
|
||||
if (path.empty())
|
||||
{
|
||||
LOGI("Package OpenCV of version %s is not installed. Try to install it :)", norm_version.c_str());
|
||||
LOGI("Package OpenCV of version \"%s\" (%d) is not installed. Try to install it :)", String8(version).string(), norm_version);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -107,7 +91,7 @@ String16 OpenCVEngine::GetLibPathByVersion(android::String16 version)
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("OpenCV version \"%s\" (%s) is not supported", String8(version).string(), norm_version.c_str());
|
||||
LOGE("OpenCV version \"%s\" (%d) is not supported", String8(version).string(), norm_version);
|
||||
}
|
||||
|
||||
return String16(path.c_str());
|
||||
@ -116,11 +100,11 @@ String16 OpenCVEngine::GetLibPathByVersion(android::String16 version)
|
||||
android::String16 OpenCVEngine::GetLibraryList(android::String16 version)
|
||||
{
|
||||
std::string std_version = String8(version).string();
|
||||
std::string norm_version;
|
||||
int norm_version;
|
||||
String16 result;
|
||||
norm_version = NormalizeVersionString(std_version);
|
||||
|
||||
if (!norm_version.empty())
|
||||
if (0 != norm_version)
|
||||
{
|
||||
std::string tmp = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID);
|
||||
if (!tmp.empty())
|
||||
@ -156,12 +140,12 @@ android::String16 OpenCVEngine::GetLibraryList(android::String16 version)
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGI("Package OpenCV of version %s is not installed. Try to install it :)", norm_version.c_str());
|
||||
LOGI("Package OpenCV of version \"%s\" (%d) is not installed. Try to install it :)", std_version.c_str(), norm_version);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("OpenCV version \"%s\" is not supported", norm_version.c_str());
|
||||
LOGE("OpenCV version \"%s\" is not supported", std_version.c_str());
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -170,21 +154,21 @@ android::String16 OpenCVEngine::GetLibraryList(android::String16 version)
|
||||
bool OpenCVEngine::InstallVersion(android::String16 version)
|
||||
{
|
||||
std::string std_version = String8(version).string();
|
||||
std::string norm_version;
|
||||
int norm_version;
|
||||
bool result = false;
|
||||
|
||||
LOGD("OpenCVEngine::InstallVersion() begin");
|
||||
|
||||
norm_version = NormalizeVersionString(std_version);
|
||||
|
||||
if (!norm_version.empty())
|
||||
if (0 != norm_version)
|
||||
{
|
||||
LOGD("PackageManager->InstallVersion call");
|
||||
result = PackageManager->InstallVersion(norm_version, Platform, CpuID);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("OpenCV version \"%s\" is not supported", norm_version.c_str());
|
||||
LOGE("OpenCV version \"%s\" (%d) is not supported", std_version.c_str(), norm_version);
|
||||
}
|
||||
|
||||
LOGD("OpenCVEngine::InstallVersion() end");
|
||||
|
@ -23,16 +23,15 @@ public:
|
||||
|
||||
protected:
|
||||
IPackageManager* PackageManager;
|
||||
static const std::set<std::string> KnownVersions;
|
||||
static const int KnownVersions[];
|
||||
|
||||
OpenCVEngine();
|
||||
static std::set<std::string> InitKnownOpenCVersions();
|
||||
bool ValidateVersionString(const std::string& version);
|
||||
std::string NormalizeVersionString(std::string version);
|
||||
bool ValidateVersion(int version);
|
||||
int NormalizeVersionString(std::string version);
|
||||
bool FixPermissions(const std::string& path);
|
||||
|
||||
static const int Platform;
|
||||
static const int CpuID;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -11,22 +11,24 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
set<string> CommonPackageManager::GetInstalledVersions()
|
||||
vector<int> CommonPackageManager::GetInstalledVersions()
|
||||
{
|
||||
set<string> result;
|
||||
vector<int> result;
|
||||
vector<PackageInfo> installed_packages = GetInstalledPackages();
|
||||
|
||||
for (vector<PackageInfo>::const_iterator it = installed_packages.begin(); it != installed_packages.end(); ++it)
|
||||
result.resize(installed_packages.size());
|
||||
|
||||
for (size_t i = 0; i < installed_packages.size(); i++)
|
||||
{
|
||||
string version = it->GetVersion();
|
||||
assert(!version.empty());
|
||||
result.insert(version);
|
||||
int version = installed_packages[i].GetVersion();
|
||||
assert(version);
|
||||
result[i] = version;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CommonPackageManager::CheckVersionInstalled(const std::string& version, int platform, int cpu_id)
|
||||
bool CommonPackageManager::CheckVersionInstalled(int version, int platform, int cpu_id)
|
||||
{
|
||||
bool result = false;
|
||||
LOGD("CommonPackageManager::CheckVersionInstalled() begin");
|
||||
@ -48,14 +50,14 @@ bool CommonPackageManager::CheckVersionInstalled(const std::string& version, int
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CommonPackageManager::InstallVersion(const std::string& version, int platform, int cpu_id)
|
||||
bool CommonPackageManager::InstallVersion(int version, int platform, int cpu_id)
|
||||
{
|
||||
LOGD("CommonPackageManager::InstallVersion() begin");
|
||||
PackageInfo package(version, platform, cpu_id);
|
||||
return InstallPackage(package);
|
||||
}
|
||||
|
||||
string CommonPackageManager::GetPackagePathByVersion(const std::string& version, int platform, int cpu_id)
|
||||
string CommonPackageManager::GetPackagePathByVersion(int version, int platform, int cpu_id)
|
||||
{
|
||||
string result;
|
||||
PackageInfo target_package(version, platform, cpu_id);
|
||||
@ -64,7 +66,7 @@ string CommonPackageManager::GetPackagePathByVersion(const std::string& version,
|
||||
|
||||
for (vector<PackageInfo>::iterator it = all_packages.begin(); it != all_packages.end(); ++it)
|
||||
{
|
||||
LOGD("Check version \"%s\" compatibility with \"%s\"\n", version.c_str(), it->GetVersion().c_str());
|
||||
LOGD("Check version \"%d\" compatibility with \"%d\"\n", version, it->GetVersion());
|
||||
if (IsVersionCompatible(version, it->GetVersion()))
|
||||
{
|
||||
LOGD("Compatible");
|
||||
@ -79,7 +81,7 @@ string CommonPackageManager::GetPackagePathByVersion(const std::string& version,
|
||||
if (!packages.empty())
|
||||
{
|
||||
int OptRating = -1;
|
||||
std::string OptVersion = "";
|
||||
int OptVersion = 0;
|
||||
std::vector<std::pair<int, int> >& group = CommonPackageManager::ArmRating;
|
||||
|
||||
if ((cpu_id & ARCH_X86) || (cpu_id & ARCH_X64))
|
||||
@ -124,20 +126,13 @@ string CommonPackageManager::GetPackagePathByVersion(const std::string& version,
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CommonPackageManager::IsVersionCompatible(const std::string& target_version, const std::string& package_version)
|
||||
bool CommonPackageManager::IsVersionCompatible(int target_version, int package_version)
|
||||
{
|
||||
assert (target_version.size() == 3);
|
||||
assert (package_version.size() == 3);
|
||||
|
||||
bool result = false;
|
||||
assert(target_version);
|
||||
assert(package_version);
|
||||
|
||||
// major version is the same and minor package version is above or the same as target.
|
||||
if ((package_version[0] == target_version[0]) && (package_version[1] == target_version[1]) && (package_version[2] >= target_version[2]))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
return ( (package_version/10000 == target_version/10000) && (package_version%10000 >= target_version%10000) );
|
||||
}
|
||||
|
||||
int CommonPackageManager::GetHardwareRating(int platform, int cpu_id, const std::vector<std::pair<int, int> >& group)
|
||||
|
@ -3,17 +3,16 @@
|
||||
|
||||
#include "IPackageManager.h"
|
||||
#include "PackageInfo.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class CommonPackageManager: public IPackageManager
|
||||
{
|
||||
public:
|
||||
std::set<std::string> GetInstalledVersions();
|
||||
bool CheckVersionInstalled(const std::string& version, int platform, int cpu_id);
|
||||
bool InstallVersion(const std::string& version, int platform, int cpu_id);
|
||||
std::string GetPackagePathByVersion(const std::string& version, int platform, int cpu_id);
|
||||
std::vector<int> GetInstalledVersions();
|
||||
bool CheckVersionInstalled(int version, int platform, int cpu_id);
|
||||
bool InstallVersion(int version, int platform, int cpu_id);
|
||||
std::string GetPackagePathByVersion(int version, int platform, int cpu_id);
|
||||
virtual ~CommonPackageManager();
|
||||
|
||||
protected:
|
||||
@ -23,7 +22,7 @@ protected:
|
||||
static std::vector<std::pair<int, int> > InitArmRating();
|
||||
static std::vector<std::pair<int, int> > InitIntelRating();
|
||||
|
||||
bool IsVersionCompatible(const std::string& target_version, const std::string& package_version);
|
||||
bool IsVersionCompatible(int target_version, int package_version);
|
||||
int GetHardwareRating(int platform, int cpu_id, const std::vector<std::pair<int, int> >& group);
|
||||
|
||||
virtual bool InstallPackage(const PackageInfo& package) = 0;
|
||||
@ -31,4 +30,4 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -124,14 +124,19 @@ inline int SplitIntelFeatures(const vector<string>& features)
|
||||
return result;
|
||||
}
|
||||
|
||||
inline string SplitVersion(const vector<string>& features, const string& package_version)
|
||||
inline int SplitVersion(const vector<string>& features, const string& package_version)
|
||||
{
|
||||
string result;
|
||||
int result = 0;
|
||||
|
||||
if ((features.size() > 1) && ('v' == features[1][0]))
|
||||
{
|
||||
result = features[1].substr(1);
|
||||
result += SplitStringVector(package_version, '.')[0];
|
||||
// Taking major and minor mart of library version from package name
|
||||
string tmp1 = features[1].substr(1);
|
||||
result += atoi(tmp1.substr(0,1).c_str())*1000000 + atoi(tmp1.substr(1,1).c_str())*10000;
|
||||
|
||||
// Taking release and build number from package revision
|
||||
vector<string> tmp2 = SplitStringVector(package_version, '.');
|
||||
result += atoi(tmp2[0].c_str())*100 + atoi(tmp2[1].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -186,9 +191,9 @@ inline int SplitPlatfrom(const vector<string>& features)
|
||||
* Second part is version. Version starts from "v" symbol. After "v" symbol version nomber without dot symbol added.
|
||||
* If platform is known third part is platform name
|
||||
* If platform is unknown it is defined by hardware capabilities using pattern: <arch>_<floating point and vectorization features>_<other features>
|
||||
* Example: armv7_neon, armv5_vfpv3
|
||||
* Example: armv7_neon
|
||||
*/
|
||||
PackageInfo::PackageInfo(const string& version, int platform, int cpu_id, std::string install_path):
|
||||
PackageInfo::PackageInfo(int version, int platform, int cpu_id, std::string install_path):
|
||||
Version(version),
|
||||
Platform(platform),
|
||||
CpuID(cpu_id),
|
||||
@ -198,7 +203,14 @@ InstallPath("")
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
#endif
|
||||
|
||||
FullName = BasePackageName + "_v" + Version.substr(0, Version.size()-1);
|
||||
int major_version = version/1000000;
|
||||
int minor_version = version/10000 - major_version*100;
|
||||
|
||||
char tmp[32];
|
||||
|
||||
sprintf(tmp, "%d%d", major_version, minor_version);
|
||||
|
||||
FullName = BasePackageName + std::string("_v") + std::string(tmp);
|
||||
if (PLATFORM_UNKNOWN != Platform)
|
||||
{
|
||||
FullName += string("_") + JoinPlatform(platform);
|
||||
@ -296,7 +308,7 @@ InstallPath("")
|
||||
else
|
||||
{
|
||||
LOGD("PackageInfo::PackageInfo: package arch unknown");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
}
|
||||
@ -304,7 +316,7 @@ InstallPath("")
|
||||
else
|
||||
{
|
||||
LOGD("PackageInfo::PackageInfo: package arch unknown");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
}
|
||||
@ -371,7 +383,7 @@ InstallPath(install_path)
|
||||
{
|
||||
LOGI("Info library not found in package");
|
||||
LOGI("OpenCV Manager package does not contain any verison of OpenCV library");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
return;
|
||||
@ -383,7 +395,7 @@ InstallPath(install_path)
|
||||
if (!features.empty() && (BasePackageName == features[0]))
|
||||
{
|
||||
Version = SplitVersion(features, package_version);
|
||||
if (Version.empty())
|
||||
if (0 == Version)
|
||||
{
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
@ -410,7 +422,7 @@ InstallPath(install_path)
|
||||
if (features.size() < 3)
|
||||
{
|
||||
LOGD("It is not OpenCV library package for this platform");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
return;
|
||||
@ -444,7 +456,7 @@ InstallPath(install_path)
|
||||
else
|
||||
{
|
||||
LOGD("It is not OpenCV library package for this platform");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
return;
|
||||
@ -454,7 +466,7 @@ InstallPath(install_path)
|
||||
else
|
||||
{
|
||||
LOGD("It is not OpenCV library package for this platform");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
return;
|
||||
@ -463,7 +475,7 @@ InstallPath(install_path)
|
||||
|
||||
bool PackageInfo::IsValid() const
|
||||
{
|
||||
return !(Version.empty() && (PLATFORM_UNKNOWN == Platform) && (ARCH_UNKNOWN == CpuID));
|
||||
return !((0 == Version) && (PLATFORM_UNKNOWN == Platform) && (ARCH_UNKNOWN == CpuID));
|
||||
}
|
||||
|
||||
int PackageInfo::GetPlatform() const
|
||||
@ -481,7 +493,7 @@ string PackageInfo::GetFullName() const
|
||||
return FullName;
|
||||
}
|
||||
|
||||
string PackageInfo::GetVersion() const
|
||||
int PackageInfo::GetVersion() const
|
||||
{
|
||||
return Version;
|
||||
}
|
||||
@ -494,4 +506,4 @@ string PackageInfo::GetInstalationPath() const
|
||||
bool PackageInfo::operator==(const PackageInfo& package) const
|
||||
{
|
||||
return (package.FullName == FullName);
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,10 @@
|
||||
class PackageInfo
|
||||
{
|
||||
public:
|
||||
PackageInfo(const std::string& version, int platform, int cpu_id, std::string install_path = "/data/data/");
|
||||
PackageInfo(int version, int platform, int cpu_id, std::string install_path = "/data/data/");
|
||||
PackageInfo(const std::string& fullname, const std::string& install_path, std::string package_version = "0.0");
|
||||
std::string GetFullName() const;
|
||||
std::string GetVersion() const;
|
||||
int GetVersion() const;
|
||||
int GetPlatform() const;
|
||||
int GetCpuID() const;
|
||||
std::string GetInstalationPath() const;
|
||||
@ -43,7 +43,7 @@ public:
|
||||
|
||||
protected:
|
||||
static std::map<int, std::string> InitPlatformNameMap();
|
||||
std::string Version;
|
||||
int Version;
|
||||
int Platform;
|
||||
int CpuID;
|
||||
std::string FullName;
|
||||
@ -51,4 +51,4 @@ protected:
|
||||
static const std::string BasePackageName;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,17 +1,17 @@
|
||||
#ifndef __IPACKAGE_MANAGER__
|
||||
#define __IPACKAGE_MANAGER__
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class IPackageManager
|
||||
{
|
||||
public:
|
||||
virtual std::set<std::string> GetInstalledVersions() = 0;
|
||||
virtual bool CheckVersionInstalled(const std::string& version, int platform, int cpu_id) = 0;
|
||||
virtual bool InstallVersion(const std::string&, int platform, int cpu_id) = 0;
|
||||
virtual std::string GetPackagePathByVersion(const std::string&, int platform, int cpu_id) = 0;
|
||||
virtual std::vector<int> GetInstalledVersions() = 0;
|
||||
virtual bool CheckVersionInstalled(int version, int platform, int cpu_id) = 0;
|
||||
virtual bool InstallVersion(int version, int platform, int cpu_id) = 0;
|
||||
virtual std::string GetPackagePathByVersion(int version, int platform, int cpu_id) = 0;
|
||||
virtual ~IPackageManager(){};
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -26,7 +26,7 @@
|
||||
android:id="@+id/textView1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Version: "
|
||||
android:text="Library version: "
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
|
@ -30,7 +30,7 @@
|
||||
android:id="@+id/EngineVersionCaption"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Version: "
|
||||
android:text="OpenCV Manager version: "
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
|
Loading…
Reference in New Issue
Block a user