diff --git a/app/build.gradle b/app/build.gradle index c9f88b76..a380e3e1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,6 +45,8 @@ dependencies { implementation "com.github.topjohnwu.libsu:core:${libsuVersion}" implementation "com.github.topjohnwu.libsu:service:${libsuVersion}" implementation "com.github.topjohnwu.libsu:nio:${libsuVersion}" + implementation "org.lsposed.hiddenapibypass:hiddenapibypass:4.3" + compileOnly project(":hiddenapi:stubs") implementation "eu.chainfire:libsuperuser:1.1.0" implementation "com.github.ukanth:android-lockpattern:8.0.4" implementation "com.afollestad.material-dialogs:core:0.9.6.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 21f4d7f8..79427512 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -50,6 +50,7 @@ + @@ -356,4 +357,4 @@ - \ No newline at end of file + diff --git a/app/src/main/java/dev/ukanth/ufirewall/Api.java b/app/src/main/java/dev/ukanth/ufirewall/Api.java index cdba365a..f4182a89 100644 --- a/app/src/main/java/dev/ukanth/ufirewall/Api.java +++ b/app/src/main/java/dev/ukanth/ufirewall/Api.java @@ -123,6 +123,7 @@ import javax.crypto.spec.DESKeySpec; import dev.ukanth.ufirewall.MainActivity.GetAppList; +import dev.ukanth.ufirewall.MultiUser; import dev.ukanth.ufirewall.log.Log; import dev.ukanth.ufirewall.log.LogData; import dev.ukanth.ufirewall.log.LogData_Table; @@ -168,6 +169,7 @@ public final class Api { public static final int NOTIFICATION_ID = 1; public static final String PREF_FIREWALL_STATUS = "AFWallStaus"; public static final String DEFAULT_PREFS_NAME = "AFWallPrefs"; + public static final String CACHE_PREFS_NAME = "AFWallCache"; //for import/export rules //revertback to old approach for performance public static final String PREF_3G_PKG_UIDS = "AllowedPKG3G_UIDS"; @@ -1395,33 +1397,38 @@ public static List getApps(Context ctx, GetAppList appList) { } //revert back to old approach - //always use the defaul preferences to store cache value - reduces the application usage size - SharedPreferences cachePrefs = ctx.getSharedPreferences(DEFAULT_PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences cachePrefs = ctx.getSharedPreferences(CACHE_PREFS_NAME, Context.MODE_PRIVATE); int count = 0; try { - listOfUids = new ArrayList<>(); - //this code will be executed on devices running ICS or later - final UserManager um = (UserManager) ctx.getSystemService(Context.USER_SERVICE); - List list = um.getUserProfiles(); - - for (UserHandle user : list) { - Matcher m = p.matcher(user.toString()); - if (m.find() && m.groupCount() > 0) { - int id = Integer.parseInt(m.group(1)); - if (id > 0) { - listOfUids.add(id); + /*if(G.supportDual()) { + listOfUids = new ArrayList<>(); + //this code will be executed on devices running ICS or later + final UserManager um = (UserManager) ctx.getSystemService(Context.USER_SERVICE); + List list = um.getUserProfiles(); + + for (UserHandle user : list) { + Matcher m = p.matcher(user.toString()); + if (m.find() && m.groupCount() > 0) { + int id = Integer.parseInt(m.group(1)); + if (id > 0) { + listOfUids.add(id); + } } } - } - //use pm list packages -f -U --user 10 - int pkgManagerFlags = PackageManager.GET_META_DATA; - // it's useless to iterate over uninstalled packages if we don't support multi-profile apps - if (G.supportDual()) { - pkgManagerFlags |= PackageManager.GET_UNINSTALLED_PACKAGES; - } + }*/ PackageManager pkgmanager = ctx.getPackageManager(); - List installed = pkgmanager.getInstalledApplications(pkgManagerFlags); + List installed; + if (G.isMultiUser()) { + installed = MultiUser.getInstalledPackagesFromAllUsers(MultiUser.MATCH_ALL_METADATA); + } else { + int pkgManagerFlags = PackageManager.GET_META_DATA; + // it's useless to iterate over uninstalled packages if we don't support multi-profile apps + if (G.supportDual()) { + pkgManagerFlags |= PackageManager.GET_UNINSTALLED_PACKAGES; + } + installed = pkgmanager.getInstalledPackages(pkgManagerFlags); + } SparseArray syncMap = new SparseArray<>(); Editor edit = cachePrefs.edit(); boolean changed = false; @@ -1429,21 +1436,24 @@ public static List getApps(Context ctx, GetAppList appList) { String cachekey; String cacheLabel = "cache.label."; PackageInfoData app; - ApplicationInfo apinfo; Date install = new Date(); install.setTime(System.currentTimeMillis() - (180000)); SparseArray multiUserAppsMap = new SparseArray<>(); HashMap packagesForUser = new HashMap<>(); - if(G.supportDual()) { + /*if(G.supportDual()) { packagesForUser = getPackagesForUser(listOfUids); - } + }*/ + + + for (PackageInfo pkginfo : installed) { + ApplicationInfo apinfo = pkginfo.applicationInfo; + if (apinfo == null) continue; - for (int i = 0; i < installed.size(); i++) { - //for (ApplicationInfo apinfo : installed) { + int user_id = MultiUser.applicationUserId(apinfo); + Log.d(TAG, "Processing app info: " + apinfo.packageName + " / user " + user_id + " / uid " + apinfo.uid); count = count + 1; - apinfo = installed.get(i); if (appList != null) { appList.doProgress(count); @@ -1456,11 +1466,15 @@ public static List getApps(Context ctx, GetAppList appList) { continue; } // try to get the application label from our cache - getApplicationLabel() is horribly slow!!!! - cachekey = cacheLabel + apinfo.packageName; + cachekey = cacheLabel + apinfo.packageName + Integer.toString(user_id); name = prefs.getString(cachekey, ""); if (name.length() == 0 || isRecentlyInstalled(apinfo.packageName)) { // get label and put on cache - name = pkgmanager.getApplicationLabel(apinfo).toString(); + if (G.isMultiUser()) { + name = pkgmanager.getApplicationLabel(apinfo).toString() + " / user " + Integer.toString(user_id); + } else { + name = pkgmanager.getApplicationLabel(apinfo).toString(); + } edit.putString(cachekey, name); changed = true; firstseen = true; @@ -1480,8 +1494,7 @@ public static List getApps(Context ctx, GetAppList appList) { app.appType = 0; } app.pkgName = apinfo.packageName; - if ((apinfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0) - syncMap.put(apinfo.uid, app); + syncMap.put(app.uid, app); } else { app.names.add(name); } @@ -1509,12 +1522,12 @@ public static List getApps(Context ctx, GetAppList appList) { if (G.enableTor() && !app.selected_tor && Collections.binarySearch(selected_tor, app.uid) >= 0) { app.selected_tor = true; } - if (G.supportDual()) { + /*if (G.supportDual()) { checkPartOfMultiUser(apinfo, name, listOfUids, packagesForUser, multiUserAppsMap); - } + }*/ } - if (G.supportDual()) { + /*if (G.supportDual()) { //run through multi user map for (int i = 0; i < multiUserAppsMap.size(); i++) { app = multiUserAppsMap.valueAt(i); @@ -1541,7 +1554,7 @@ public static List getApps(Context ctx, GetAppList appList) { } syncMap.put(app.uid, app); } - } + }*/ List specialData = getSpecialData(); @@ -1636,7 +1649,7 @@ public static List getSpecialData() { return specialData; } - private static void checkPartOfMultiUser(ApplicationInfo apinfo, String name, List uid1, HashMap pkgs, SparseArray syncMap) { + /*private static void checkPartOfMultiUser(ApplicationInfo apinfo, String name, List uid1, HashMap pkgs, SparseArray syncMap) { try { for (Integer integer : uid1) { int appUid = Integer.parseInt(integer + "" + apinfo.uid + ""); @@ -1666,7 +1679,7 @@ private static void checkPartOfMultiUser(ApplicationInfo apinfo, String name, Li } catch (Exception e) { Log.e(TAG, e.getMessage(), e); } - } + }*/ private static boolean packagesExistForUserUid(HashMap pkgs, int appUid) { if(pkgs.containsKey(appUid)){ @@ -2357,16 +2370,36 @@ private static Map getCurrentRulesAsMap(Context ctx) { Map exportMap = new HashMap<>(); try { - for (PackageInfoData app : apps) { - if (app.selected_wifi || app.selected_3g || app.selected_roam || app.selected_vpn || - app.selected_tether || app.selected_lan || app.selected_tor) { - updateExportPackage(exportMap, app.pkgName, WIFI_EXPORT); - updateExportPackage(exportMap, app.pkgName, DATA_EXPORT); - updateExportPackage(exportMap, app.pkgName, ROAM_EXPORT); - updateExportPackage(exportMap, app.pkgName, VPN_EXPORT); - updateExportPackage(exportMap, app.pkgName, TETHER_EXPORT); - updateExportPackage(exportMap, app.pkgName, LAN_EXPORT); - updateExportPackage(exportMap, app.pkgName, TOR_EXPORT); + for (int i = 0; i < apps.size(); i++) { + PackageInfoData pkginfo = apps.get(i); + String packageName = pkginfo.pkgName; + if (G.isMultiUser()) { + int user_id = MultiUser.applicationUserId(pkginfo.appinfo); + if (user_id > 0) { + packageName = packageName + "/" + String.valueOf(user_id); + } + } + + if (apps.get(i).selected_wifi) { + updateExportPackage(exportMap, packageName, WIFI_EXPORT); + } + if (apps.get(i).selected_3g) { + updateExportPackage(exportMap, packageName, DATA_EXPORT); + } + if (apps.get(i).selected_roam) { + updateExportPackage(exportMap, packageName, ROAM_EXPORT); + } + if (apps.get(i).selected_vpn) { + updateExportPackage(exportMap, packageName, VPN_EXPORT); + } + if (apps.get(i).selected_tether) { + updateExportPackage(exportMap, packageName, TETHER_EXPORT); + } + if (apps.get(i).selected_lan) { + updateExportPackage(exportMap, packageName, LAN_EXPORT); + } + if (apps.get(i).selected_tor) { + updateExportPackage(exportMap, packageName, TOR_EXPORT); } } } catch (JSONException e) { @@ -2596,10 +2629,19 @@ private static void updateRulesFromJson(Context ctx, JSONObject object, String p uidBuilders[TOR_EXPORT] = new StringBuilder(); Map json = JsonHelper.toMap(object); + Map muPackages = null; final PackageManager pm = ctx.getPackageManager(); for (Map.Entry entry : json.entrySet()) { String pkgName = entry.getKey(); + int user_id = 0; + if (G.isMultiUser()) { + if (pkgName.contains("/")) { + String[] parts = pkgName.split("/"); + pkgName = parts[0]; + user_id = Integer.parseInt(parts[1]); + } + } if (pkgName.contains(":")) { pkgName = pkgName.split(":")[0]; } @@ -2618,10 +2660,30 @@ private static void updateRulesFromJson(Context ctx, JSONObject object, String p if (pkgName.startsWith("dev.afwall.special")) { uidBuilder.append(specialApps.get(pkgName)); } else { - try { - uidBuilder.append(pm.getApplicationInfo(pkgName, 0).uid); - } catch (NameNotFoundException e) { - // Handle exception if needed + if (user_id > 0) { + if (muPackages == null) { + // build cache of all installed packages + muPackages = new HashMap(); + List apps = getApps(ctx, null); + for (PackageInfoData pkginfo : apps) { + int user_id_ = MultiUser.applicationUserId(pkginfo.appinfo); + if (user_id_ > 0) { + muPackages.put(pkginfo.pkgName + "/" + String.valueOf(user_id_), pkginfo); + } + } + } + PackageInfoData pkginfo = muPackages.get(pkgName + "/" + String.valueOf(user_id)); + if (pkginfo != null) { + uidBuilder.append(pkginfo.uid); + } else { + // Handle not found if needed + } + } else { + try { + uidBuilder.append(pm.getApplicationInfo(pkgName, 0).uid); + } catch (NameNotFoundException e) { + // Handle exception if needed + } } } } @@ -2755,7 +2817,7 @@ public static boolean loadSharedPreferencesFromFile(Context ctx, StringBuilder b public static void probeLogTarget(final Context ctx) { } - + @SuppressLint("InlinedApi") public static void showInstalledAppDetails(Context context, String packageName) { final String SCHEME = "package"; @@ -3263,7 +3325,7 @@ public static final class PackageInfoData { public String pkgName; /** - * Application Type + * Application Type. 0 for system, 1 for user, 2 for core. */ public int appType; @@ -3379,13 +3441,12 @@ public String toString() { public String toStringWithUID() { if (tostr == null) { StringBuilder s = new StringBuilder(); - s.append("[ "); - s.append(uid); - s.append(" ] "); for (int i = 0; i < names.size(); i++) { if (i != 0) s.append(", "); s.append(names.get(i)); } + s.append(" / "); + s.append(uid); s.append("\n"); tostr = s.toString(); } diff --git a/app/src/main/java/dev/ukanth/ufirewall/MainActivity.java b/app/src/main/java/dev/ukanth/ufirewall/MainActivity.java index 292bf2bd..a5e8098a 100644 --- a/app/src/main/java/dev/ukanth/ufirewall/MainActivity.java +++ b/app/src/main/java/dev/ukanth/ufirewall/MainActivity.java @@ -101,6 +101,7 @@ import dev.ukanth.ufirewall.activity.OldLogActivity; import dev.ukanth.ufirewall.activity.RulesActivity; import dev.ukanth.ufirewall.log.Log; +import dev.ukanth.ufirewall.MultiUser; import dev.ukanth.ufirewall.preferences.PreferencesActivity; import dev.ukanth.ufirewall.profiles.ProfileData; import dev.ukanth.ufirewall.profiles.ProfileHelper; @@ -233,6 +234,7 @@ public void onCreate(Bundle savedInstanceState) { startRootShell(); new SecurityUtil(MainActivity.this).passCheck(); registerNetworkObserver(); + MultiUser.setup(); } registerUIbroadcast4(); registerUIbroadcast6(); @@ -997,8 +999,11 @@ private void showApplications(final String searchStr) { for (PackageInfoData app : apps) { for (String str : app.names) { if (str != null && searchStr != null) { + if (unique.contains(app.uid)) { + continue; + } if (str.contains(searchStr.toLowerCase()) || str.toLowerCase().contains(searchStr.toLowerCase()) - && !searchApp.contains(app) || (G.showUid() && (str + " " + app.uid).contains(searchStr) && !unique.contains(app.uid))) { + && !searchApp.contains(app) || (G.showUid() && (str + " " + app.uid).contains(searchStr))) { searchApp.add(app); unique.add(app.uid); isResultsFound = true; diff --git a/app/src/main/java/dev/ukanth/ufirewall/MultiUser.java b/app/src/main/java/dev/ukanth/ufirewall/MultiUser.java new file mode 100644 index 00000000..46837edb --- /dev/null +++ b/app/src/main/java/dev/ukanth/ufirewall/MultiUser.java @@ -0,0 +1,174 @@ +package dev.ukanth.ufirewall; + +import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageManager; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ParceledListSlice; +import android.content.pm.UserInfo; +import android.os.Build; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import com.topjohnwu.superuser.Shell; + +import org.lsposed.hiddenapibypass.HiddenApiBypass; + +import dev.ukanth.ufirewall.log.Log; + + +public class MultiUser { + public static final String TAG = "AFWall"; + + private static final Pattern list_users = Pattern.compile("\\s*UserInfo\\{(.*?):(.*):(.*?)\\}.*", Pattern.MULTILINE); + + // just call `pm list users` directly - the HiddenApi IUserManager dance still + // requires MANAGE_USERS which has android:protectionLevel="signature|privileged" + // so there is no way for us to get it even with root su shell. + public static List getUsers() { + Shell.Result result = Shell.cmd("pm list users").exec(); + List res = new ArrayList(); + if (!result.isSuccess()) { + Log.w(TAG, "pm list users failed; further errors likely"); + return res; + } + List out = result.getOut(); + Matcher matcher; + for (String item : out) { + matcher = list_users.matcher(item); + if (matcher.find() && matcher.groupCount() > 0) { + int user_id = Integer.parseInt(matcher.group(1)); + String username = matcher.group(2); + int flag = Integer.parseInt(matcher.group(3), 16); + UserInfo ui = new UserInfo(); + ui.id = user_id; + ui.name = username; + //ui.flags = flag; // hiddenapi-stub doesn't yet expose this, we don't need it anyway + res.add(ui); + } + } + return res; + } + + public static void setup() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + HiddenApiBypass.addHiddenApiExemptions(""); + } + + Shell.Result result = Shell.cmd("pm grant dev.ukanth.ufirewall android.permission.INTERACT_ACROSS_USERS").exec(); + if (!result.isSuccess()) { + Log.w(TAG, "pm grant INTERACT_ACROSS_USERS failed; further errors likely"); + } + } + + // Copied from LSPosed daemon/**/PackageService.java + private static IBinder pbinder = null; + private static IPackageManager pm = null; + public static final int PER_USER_RANGE = 100000; + + // Copied from LSPosed daemon/**/PackageService.java + // We drop MATCH_ANY_USER as we don't need it, and it requires MANAGE_USERS which we can't get, as explained above + public static final int MATCH_ALL_FLAGS = PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_UNINSTALLED_PACKAGES; // | MATCH_ANY_USER; + + public static final int MATCH_ALL_METADATA = PackageManager.GET_META_DATA | MATCH_ALL_FLAGS; + + // Copied from LSPosed daemon/**/PackageService.java + private static final IBinder.DeathRecipient precipient = new IBinder.DeathRecipient() { + @Override + public void binderDied() { + Log.w(TAG, "pm is dead"); + pbinder.unlinkToDeath(this, 0); + pbinder = null; + pm = null; + } + }; + + // Copied from LSPosed daemon/**/PackageService.java + private static IPackageManager getPackageManager() { + if (pbinder == null || pm == null) { + pbinder = ServiceManager.getService("package"); + if (pbinder == null) return null; + try { + pbinder.linkToDeath(precipient, 0); + } catch (RemoteException e) { + Log.e(TAG, android.util.Log.getStackTraceString(e)); + } + pm = IPackageManager.Stub.asInterface(pbinder); + } + return pm; + } + + // Copied from LSPosed daemon/**/PackageService.java + public static boolean isPackageAvailable(String packageName, int userId, boolean ignoreHidden) throws RemoteException { + // Unlike LSPosed, we do not check getApplicationHiddenSettingAsUser + // because this requires MANAGE_USERS permission (on some versions of + // Android) which we cannot get, as explained above. + // + // Normally, it would return whether the user manually hid their app in + // their list of apps. This is used by the system home app to hide the + // app in the home screen only - but the app still shows up in the + // system "all apps" settings. Likewise, hiding these apps within + // AFWall seems a bit pointless. It is unclear why LSPosed themselves + // do it. Their original PR is here: + // https://github.com/LSPosed/LSPosed/pull/852 + return pm.isPackageAvailable(packageName, userId); // || (ignoreHidden && pm.getApplicationHiddenSettingAsUser(packageName, userId)); + } + + public static int packageUserId(PackageInfo info) { + return applicationUserId(info.applicationInfo); + } + + public static int applicationUserId(ApplicationInfo info) { + return (info == null)? -1: info.uid / PER_USER_RANGE; + } + + // Copied from LSPosed daemon/**/PackageService.java + // This requires INTERACT_ACROSS_USERS permission. LSPosed already has it, but + // we need to grant it at runtime - make sure you call setup() in app.onCreate(_) + // We use this instead of `pm list packages` so that we have ApplicationInfo + // objects, which allows us to get the icons and labels in a convenient manner. + public static List getInstalledPackagesFromAllUsers(int flags/*, boolean filterNoProcess*/) throws RemoteException { + List res = new ArrayList<>(); + IPackageManager pm = getPackageManager(); + if (pm == null) return res; + for (UserInfo user : getUsers()) { + // in case pkginfo of other users in primary user + ParceledListSlice infos; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + infos = pm.getInstalledPackages((long) flags, user.id); + } else { + infos = pm.getInstalledPackages(flags, user.id); + } + res.addAll(infos + .getList().parallelStream() + .filter(info -> info.applicationInfo != null && packageUserId(info) == user.id) + .filter(info -> { + try { + return isPackageAvailable(info.packageName, user.id, true); + } catch (RemoteException e) { + return false; + } + }) + .collect(Collectors.toList())); + } + /*if (filterNoProcess) { + return new ParcelableListSlice<>(res.parallelStream().filter(packageInfo -> { + try { + PackageInfo pkgInfo = getPackageInfoWithComponents(packageInfo.packageName, MATCH_ALL_FLAGS, packageInfo.applicationInfo.uid / PER_USER_RANGE); + return !fetchProcesses(pkgInfo).isEmpty(); + } catch (RemoteException e) { + Log.w(TAG, "filter failed", e); + return true; + } + }).collect(Collectors.toList())); + }*/ + return res; + } +} diff --git a/app/src/main/java/dev/ukanth/ufirewall/preferences/ExpPreferenceFragment.java b/app/src/main/java/dev/ukanth/ufirewall/preferences/ExpPreferenceFragment.java index f7e7e170..84ef288f 100644 --- a/app/src/main/java/dev/ukanth/ufirewall/preferences/ExpPreferenceFragment.java +++ b/app/src/main/java/dev/ukanth/ufirewall/preferences/ExpPreferenceFragment.java @@ -7,6 +7,7 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -149,6 +150,11 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, } else { Api.setUserOwner(this.getActivity().getApplicationContext()); } + final Context ctx = getActivity().getApplicationContext(); + SharedPreferences cachePrefs = ctx.getSharedPreferences(Api.CACHE_PREFS_NAME, Context.MODE_PRIVATE); + Editor edit = cachePrefs.edit(); + edit.clear(); + edit.apply(); } } diff --git a/app/src/main/java/dev/ukanth/ufirewall/util/AppListArrayAdapter.java b/app/src/main/java/dev/ukanth/ufirewall/util/AppListArrayAdapter.java index 11fe46c0..7fff9268 100644 --- a/app/src/main/java/dev/ukanth/ufirewall/util/AppListArrayAdapter.java +++ b/app/src/main/java/dev/ukanth/ufirewall/util/AppListArrayAdapter.java @@ -145,11 +145,11 @@ public View getView(final int position, View convertView, ViewGroup parent) { ApplicationInfo info = holder.app.appinfo; - if (info != null && (info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { + if (holder.app.appType == 1) { //user app holder.text.setTextColor(G.userColor()); } else { - //system app + //system or core app holder.text.setTextColor(G.sysColor()); } diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index d3455a54..40e1ea75 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -293,7 +293,7 @@ تطبيق القواعد على تبديل الأوضاع تحميل وتطبيق القواعد عند التبديل بين ملفات التعريف تفعيل دعم تعدد المستخدمين - دعم تعدد المستخدمين للنظام (يعمل فقط في الوضع حيث يتم حظر العناصر المحددة) + دعم تعدد المستخدمين للنظام حماية إضافية - منع إلغاء تثبيت AFWall+ تفاصيل حركة البيانات diff --git a/app/src/main/res/values-ast-rES/strings.xml b/app/src/main/res/values-ast-rES/strings.xml index 3f5dfe2a..d0503421 100644 --- a/app/src/main/res/values-ast-rES/strings.xml +++ b/app/src/main/res/values-ast-rES/strings.xml @@ -293,7 +293,7 @@ Aplicar regles na conmutación de perfiles Carga y aplica les regles al camudar de perfiles Habilitar sofitu multi-usuariu - Sofita la carauterística de multi-usuariu d\'Android (namái furrula nel mou u se bloquien los elementos bloquiaos) + Sofita la carauterística de multi-usuariu d\'Android Seguranza adicional - Evita la desinstalación d\'AFWall+ Detalles de tráficu diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index b0c556b4..caa7741a 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Trafik təfsilatları diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 8020f4ce..1a82fcc8 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -293,7 +293,7 @@ Прилагай при смяна Зареждане и прилагане правила при превключване между профили Разреши многопотребителски режим - Поддръжка на Андроид многопотребителски режим (работи само в режим, където избраните елементи са блокирани) + Поддръжка на Андроид многопотребителски режим Допълнителна защита - предотвратява деинсталирането на AFWall + Трафик детайли diff --git a/app/src/main/res/values-bi/strings.xml b/app/src/main/res/values-bi/strings.xml index da8ffe07..3715e1b5 100644 --- a/app/src/main/res/values-bi/strings.xml +++ b/app/src/main/res/values-bi/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 2cb4e600..e12d1760 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -293,7 +293,7 @@ নিয়ম প্রয়োগ করুন প্রোফাইল পরিবর্তনের সময় এটি লোড এবং প্রয়োগ করবে প্রোফাইল পরিবর্তনের সময় একাধিক-ব্যবহারকারী সমর্থন সক্রিয় করুন - অ্যান্ড্রয়েড মাল্টি-ইউজার (শুধুমাত্র কাজ যেখানে নির্বাচিত বিষয়োপকরণসমূহ আবদ্ধ পরিমণ্ডলে) সমর্থন + অ্যান্ড্রয়েড মাল্টি-ইউজার সমর্থন বাড়তি নিরাপত্তা - AFWall + আনইনস্টল প্রতিরোধ বিস্তারিত ট্রাফিক diff --git a/app/src/main/res/values-bs/strings.xml b/app/src/main/res/values-bs/strings.xml index 7f050763..b5b41866 100644 --- a/app/src/main/res/values-bs/strings.xml +++ b/app/src/main/res/values-bs/strings.xml @@ -293,7 +293,7 @@ Primjeni pravila kod zamjene profila Učitaj i primjeni pravila kod zamjene profila Uključi podršku za više korisnika - Podrška za Android opciju više korisnika (samo radi u modu gdje su označene stvari blokirane) + Podrška za Android opciju više korisnika Dodatna sigurnost - Spriječi brisanje AFWall+ Detalji prometa diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index adbe92a3..75c0795d 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -293,7 +293,7 @@ Aplica les regles al canviar de perfil Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 1d53c55c..7b3381a1 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -294,7 +294,7 @@ Aplikovat pravidla na přepínač profilů Načíst a aplikovat pravidla při přepínání profilů Povolit podporu více uživatelů - Podpora více uživatelů Androidu (pouze v módu kde vybrané položky jsou blokované) + Podpora více uživatelů Androidu Dodatečné zabezpečení - zabránit odinstalaci AFWall+ Podrobnosti o provozu diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 190ed9e9..c8922af2 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -293,7 +293,7 @@ Anvende regler på profil switch Indlæse og anvende regler, når du skifter profiler Aktivere understøttelse af flere brugere - Understøtter Android multi bruger (virker kun i tilstanden hvor markerede elementer er blokeret) + Understøtter Android multi bruger Ekstra sikkerhed - undgå afinstallere AFWall + Trafik detaljer diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 4d9c33cd..79d01e8b 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -293,7 +293,7 @@ Regeln bei Profilwechsel anwenden Regeln beim Profilwechsel laden und anwenden Multi-User-Unterstützung - Multi-User-Unterstützung aktivieren (nur im Modus möglich, in dem ausgewählte Elemente blockiert werden) + Multi-User-Unterstützung aktivieren Erweiterte Sicherheit - Deinstallation von AFWall+ verhindern Traffic-Details diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 2c69296b..e7f4c2fc 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -293,7 +293,7 @@ Εφαρμογή κανόνων κατά την αλλαγή προφίλ Φόρτωση και εφαρμογή κανόνων κατά την εναλλαγή προφίλ Ενεργοποίηση υποστήριξης πολλαπλών χρηστών - Υποστήριξη πολλαπλών χρηστών Android (μόνο στην λειτουργία όπου τα επιλεγμένα αντικείμενα είναι αποκλεισμένα) + Υποστήριξη πολλαπλών χρηστών Android Πρόσθετη Ασφάλεια - Αποτροπή απεγκατάστασης του AFWall+ Στατιστικά κίνησης δεδομένων diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 50f59398..b7e27002 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -293,7 +293,7 @@ Aplicar las reglas al cambiar de perfil Cargar y aplicar reglas al intercambiar perfiles Activar soporte multiusuario - Soporte multiusuario en Android (sólo funciona en modo dónde los elementos seleccionados están bloqueados) + Soporte multiusuario en Android Seguridad Adicional - Prevenir desinstalación de AFWall+ Detalles de tráfico diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 35f45626..fe2ca8e8 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -293,7 +293,7 @@ Aplikatu arauak profila aldatzean Kargatu eta aplikatu arauak profilak aldatzean Gaitu hainbat erabiltzailerentzako euskarria - Onartu hainbat Android erabiltzaile (Hautatutako elementuak blokeatuta dauden moduan besterik ez dabil) + Onartu hainbat Android erabiltzaile Segurtasun gehigarria - Eragotzi AFWall+ desinstalatzea Trafikoaren xehetasunak diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 7e50ca29..77cd6f49 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -299,7 +299,7 @@ S-OFF پیکربندی شوند. اعمال قوانین در تعویض نمایه قوانین را در هر تعویض نمایه بارگذاری و اعمال کن فعال کردن پشتیبانی چند کاربره - از اندروید چند-کاربره پشتیبانی کن (تنها در حالتی کار می‌کند که موارد انتخاب شده مسدود هستند) + از اندروید چند-کاربره پشتیبانی کن امنیت اضافی - از لغو نصب +AFWall جلوگیری می کند جزئیات ترافیک diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index da8ffe07..3715e1b5 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 27407386..7cd5efd3 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -293,7 +293,7 @@ Appliquer les règles lors du changement de profil Chargement et application des règles lors du changement de profil Activer le mode multi-utilisateur - Mode multi-utilisateur Android (fonctionne uniquement si les éléments sélectionnés sont bloqués) + Mode multi-utilisateur Android Sécurité supplémentaire - Empêcher la désinstallation de AFWall+ Détails du trafic diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 35b4b8df..d712f737 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -294,7 +294,7 @@ iptables.\nייתכן כי +AFWall לא יפעל כצפוי בשל מגבלה ז החל חוקים בהחלפת פרופיל טען והחל חוקים בעת החלפת פרופילים אפשר תמיכה במשתמשים מרובים - תמיכה בריבוי משתמשים של אנדרואיד (עובד רק במצב חסימת אפליקציות שנבחרו) + תמיכה בריבוי משתמשים של אנדרואיד אבטחה נוספת - מנע הסרת האפליקציה AFWall+ פרטי תעבורה diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 18a2381c..017bb762 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -294,7 +294,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index a78c9b27..a999ca9b 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -293,7 +293,7 @@ Primjeni pravila kod promjene profila Učitaj i primjeni pravila kod promjene profila Omogući podršku za više korisnika - Podrška za Android opciju s više korisnika (samo radi u načinu rada gdje su označene stvari blokirane) + Podrška za Android opciju s više korisnika Dodatna sigurnost - Spriječi deinstaliranje AFWall+ Detalji o prometu diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 07af7058..a3c6b923 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -293,7 +293,7 @@ Alkalmazza a szabályokat profil váltás esetén Szabályok betöltése és alkalmazása amikor profilt vált Több felhasználó támogatás engedélyezése - Android többfelhasználós mód támogatása (csak abban a módban működik, amiben a kiválasztott elemek le vannak tiltva) + Android többfelhasználós mód támogatása Kiegészítő biztonság - az AFWall+ eltávolításának megelőzése Forgalmi adatok diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 751251f7..4e8b46db 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -293,7 +293,7 @@ terapkan aturan pd pergantian profil Muat dan terapkan aturan saat berganti profil Akfitkan multi-pengguna - Dukungan multi-pengguna Android (hanya bekerja pada mode dimana item terpilih diblokir) + Dukungan multi-pengguna Android Pengamanan Tambahan - Cegah uninstall AFWall+ Detail trafik diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 9f2b6d4c..f4b42fcc 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -293,7 +293,7 @@ Applicare le regole quando si cambia profilo Carica e applica le regole al cambio dei profili Abilita il supporto multi-utente - Supporto multi-utenti di Android (funziona solo nella modalità in cui gli elementi selezionati sono bloccati) + Supporto multi-utenti di Android Protezione aggiuntiva - Impedisce la disinstallazione di AFWall + Dettagli del traffico diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 56acd6ac..bac30c78 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -296,7 +296,7 @@ プロファイル切り替え時にルールを適用 プロファイルの切り替え時にルールを読み込んで適用します マルチ ユーザーのサポートを有効にする - Android マルチ ユーザーをサポートします (選択した項目がブロックされるモードでのみ動作) + Android マルチ ユーザーをサポートします 追加のセキュリティ - AFWall+ のアンインストールを防止します トラフィック詳細 diff --git a/app/src/main/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml index da8ffe07..3715e1b5 100644 --- a/app/src/main/res/values-kn/strings.xml +++ b/app/src/main/res/values-kn/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index ca7c062a..7974a307 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -293,7 +293,7 @@ 프로필 교체시 규칙 적용 프로필 교체시 규칙을 재적용합니다. 다중사용자기능 허용 - 안드로이드 멀티유저 지원 (다만, 선택된 앱이 차단될 때만 사용가능) + 안드로이드 멀티유저 지원 기타보호기능 - AFWall+ 삭제 금지하기 트래픽 통계 diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml index 9e33cd64..eaef062b 100644 --- a/app/src/main/res/values-ku/strings.xml +++ b/app/src/main/res/values-ku/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-ky/strings.xml b/app/src/main/res/values-ky/strings.xml index 094a8a5d..b486915a 100644 --- a/app/src/main/res/values-ky/strings.xml +++ b/app/src/main/res/values-ky/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-ml-rIN/strings.xml b/app/src/main/res/values-ml-rIN/strings.xml index da8ffe07..3715e1b5 100644 --- a/app/src/main/res/values-ml-rIN/strings.xml +++ b/app/src/main/res/values-ml-rIN/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index 232ff5cd..a7723593 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -293,7 +293,7 @@ Aktifkan arahan pertukaran profil Memuatkan dan mengaktifkan arahan apabila menukar profil Aktifkan sokongan multi pengguna - Sokong pengguna multi Android (hanya berfungsi di mod terpilih yang telah disekat) + Sokong pengguna multi Android Keselamatan Tambahan - Mengelakkan AFWall+ dinyahpasang Maklumat trafik diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 792d5f02..ef82caed 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -293,7 +293,7 @@ Bruk regler ved profilbytte Last og bruk regler ved profilbytte Aktiver flerbrukerstøtte - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Trafikkdetaljer diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 4f316e89..feb0620d 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -296,7 +296,7 @@ Regels toepassen bij wisselen profiel Regels laden en toepassen bij het wisselen van profiel Multi-user ondersteuning - Ondersteuning van Android multi-user (werkt alleen in de modus waar de geselecteerde items worden geblokkeerd) + Ondersteuning van Android multi-user Extra beveiliging - Voorkom verwijderen AFWall+ Details netwerkverkeer diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 2a207e08..c5010ab3 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -293,7 +293,7 @@ Zastosuj reguły przy zmianie profilu Załaduj i zastosuj reguły podczas przełączania profili Włącz obsługę wielu użytkowników - Wsparcie dla wielu użytkowników (działa tylko w trybie, w którym wybrane elementy są blokowane) + Wsparcie dla wielu użytkowników Dodatkowe zabezpieczenie - Zapobiegaj odinstalowaniu AFWall+ Szczegóły ruchu diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index e84b9654..d63d5896 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -293,7 +293,7 @@ Aplicar regras na mudança de perfil Carregar e aplicar regras ao trocar de perfil Ativar suporte multi-usuário - Suporte multi-usuário Android (só funciona no modo onde os itens selecionados são bloqueados) + Suporte multi-usuário Android Segurança adicional - evitar desinstalar AFWall + Detalhes de tráfego diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 11dbc33b..93eaf63b 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -293,7 +293,7 @@ Aplicar regras na mudança de perfil Carregar e aplicar regras ao trocar de prfil Ativar suporte a vários utilizadores - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Segurança adicional - Impedir a desinstalação do AFWall+ Detalhes de tráfego diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 33705401..bfdda79b 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -293,7 +293,7 @@ Aplică regulile la schimbarea profilului Încarcă și aplică regulile la comutarea profilurilor Activează suportul multi-utilizator - Suportă multi-user Android (funcţionează numai în modul în care elementele selectate sunt blocate) + Suportă multi-user Android Securitate suplimentară - Previne dezinstalarea AFWall+ Detalii trafic diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index c88e64bd..bbcf87e9 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -294,7 +294,7 @@ Применять правила при смене профиля Загрузить и применить правила при переключении профилей Включить многопользовательскую поддержку - Поддержка нескольких пользователей Android (работает только в режиме, блокирующем выбранные элементы) + Поддержка нескольких пользователей Android Дополнительная безопасность - предотвратить удаление AFWall+ Подробности траффика diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index d27a350c..c4bd76b0 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -293,7 +293,7 @@ Aplikovať pravidlá pri prepnutí profilov Načítať a aplikovať pravidlá pri prepínaní profilov Povoliť podporu viacerých užívateľov - Podpora viacerých užívateľov systému Android (funguje iba v režime, kde sú blokované vybrané položky) + Podpora viacerých užívateľov systému Android Dodatočné zabezpečenie - zabráni odinštalácii AFWall + Detaily komunikácie diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 87d965c2..1f943e95 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -293,7 +293,7 @@ Uveljavi pravila Uveljavi pravila Iptables ob vsaki zamenjavi profila Vklopi večuporabniški način - Podpora za androidni večuporabniški način (deluje le v načinu, kjer so izbrane aplikacije blokirane) + Podpora za androidni večuporabniški način Varnostna nastavitev - Prepreči odstranitev AFWall+ Podatki o prometu diff --git a/app/src/main/res/values-sr-rCS/strings.xml b/app/src/main/res/values-sr-rCS/strings.xml index 2d6c6534..4ac408a7 100644 --- a/app/src/main/res/values-sr-rCS/strings.xml +++ b/app/src/main/res/values-sr-rCS/strings.xml @@ -293,7 +293,7 @@ Primeni pravila pri promeni profila Učitaj i primeni pravila kod zamene profila Uključi podršku za više korisnika - Podrška za Android opciju više korisnika (samo radi u modu gde su označene stvari blokirane) + Podrška za Android opciju više korisnika Dodatna sigurnost - Spreči brisanje AFWall+ aplikacije Detalji saobraćaja diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 30d5d89d..b672790e 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -293,7 +293,7 @@ Примени правила при промени профила Учитај и примени правила када се мења профил Укључи вишекорисничку подршку - Подршка за више корисника (ради само када се блокирају изабране ставке) + Подршка за више корисника Додатна сигурност — Заштити AFWall+ од деинсталације Детаљи саобраћаја diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index d139c595..7eb64265 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -293,7 +293,7 @@ Tillämpa regler vid profilbyte Läs in och tillämpa regler vid byte av profil Aktivera stöd för flera användare - Android fleranvändarstöd (fungerar bara i läge där markerade objekt blockeras) + Android fleranvändarstöd Extra säkerhet - förhindra att AFWall+ avinstalleras Detaljerad trafikinformation diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index e52fabc0..55132b91 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 1f072e4d..b7314911 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index ca46d479..74932b57 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -293,7 +293,7 @@ Profil geçişinde kuralları uygula Profiller değiştirildiğinde kuralları yükle ve uygula Çoklu kullanıcı desteğini etkinleştir - Android çoklu kullanıcı desteği (sadece seçilenlerin engellendiği modda çalışır) + Android çoklu kullanıcı desteği Ek Güvenlik - AFWall+ kaldırılmasını önle Trafik detayları diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index dcb71e99..691438c5 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -293,7 +293,7 @@ Застосувати правила при перемиканні профілю Завантажити і застосувати правила при перемиканні профілю Увімкнути підтримку декількох користувачів - Підтримка декількох користувачів Android (працює тільки в режимі, який блокує вибрані елементи) + Підтримка декількох користувачів Android Додатковий захист - запобігання видаленню AFWall+ Подробиці трафіку diff --git a/app/src/main/res/values-ur-rPK/strings.xml b/app/src/main/res/values-ur-rPK/strings.xml index 0df66847..6e80d903 100644 --- a/app/src/main/res/values-ur-rPK/strings.xml +++ b/app/src/main/res/values-ur-rPK/strings.xml @@ -293,7 +293,7 @@ Apply rules on profile switch Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ Traffic details diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index b4d6598d..c5032ab3 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -293,7 +293,7 @@ Áp dụng quy tắc khi đổi cấu hình Tải và áp dụng quy tắc khi đổi cấu hình Bật hỗ trợ nhiều người dùng - Hỗ trợ nhiều người dùng trên Android (chỉ hoạt động trong chế độ đánh dấu chặn) + Hỗ trợ nhiều người dùng trên Android Tăng cường bảo mật - Ngăn gỡ cài đặt AFWall+ Chi tiết lưu lượng diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 687869e1..f8b1a8fc 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -294,7 +294,7 @@ 切换配置时应用规则 切换配置文件时加载和应用规则 启用多用户支持 - 支持 Android 多用户 (仅适用于黑名单模式) + 支持 Android 多用户 额外安全措施 - 防止卸载 AFWall+ 流量详情 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 5501c20b..097d5d81 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -293,7 +293,7 @@ 設定檔案切換時套用規則 切換設定檔案時將載入並套用規則 啟用多使用者支援 - 支援 Android 多使用者 (僅適用黑名單模式) + 支援 Android 多使用者 加強安全 - 防止移除 AFWall+ 流量狀況 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 1fba1d7a..b050cbd4 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -293,7 +293,7 @@ 設定檔案切換時套用規則 切換設定檔案時將載入並套用規則 啟用多使用者支援 - 支援 Android 多使用者 (僅適用黑名單模式) + 支援 Android 多使用者 加強安全 - 防止移除 AFWall+ 流量狀況 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 15b6907a..c6aa33cd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -325,7 +325,7 @@ Load and apply rules when switching profiles Enable multi-user support - Support Android multi-user (only works in mode where selected items are blocked) + Support Android multi-user Additional Security - Prevent uninstalling AFWall+ diff --git a/hiddenapi/stubs/.gitignore b/hiddenapi/stubs/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/hiddenapi/stubs/.gitignore @@ -0,0 +1 @@ +/build diff --git a/hiddenapi/stubs/README.md b/hiddenapi/stubs/README.md new file mode 100644 index 00000000..82612a3c --- /dev/null +++ b/hiddenapi/stubs/README.md @@ -0,0 +1 @@ +copied from https://github.com/LSPosed/LSPosed/tree/master/hiddenapi/stubs diff --git a/hiddenapi/stubs/build.gradle.kts b/hiddenapi/stubs/build.gradle.kts new file mode 100644 index 00000000..384caffc --- /dev/null +++ b/hiddenapi/stubs/build.gradle.kts @@ -0,0 +1,27 @@ +/* + * This file is part of LSPosed. + * + * LSPosed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LSPosed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LSPosed. If not, see . + * + * Copyright (C) 2021 LSPosed Contributors + */ + +plugins { + `java-library` +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} diff --git a/hiddenapi/stubs/src/main/java/android/annotation/NonNull.java b/hiddenapi/stubs/src/main/java/android/annotation/NonNull.java new file mode 100644 index 00000000..927f9975 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/annotation/NonNull.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +/** + * Denotes that a parameter, field or method return value can never be null. + *

+ * This is a marker annotation and it has no specific attributes. + * + * @paramDoc This value must never be {@code null}. + * @returnDoc This value will never be {@code null}. + * @hide + */ +@Retention(SOURCE) +@Target({METHOD, PARAMETER, FIELD}) +public @interface NonNull { +} diff --git a/hiddenapi/stubs/src/main/java/android/annotation/Nullable.java b/hiddenapi/stubs/src/main/java/android/annotation/Nullable.java new file mode 100644 index 00000000..daea2b80 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/annotation/Nullable.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +/** + * Denotes that a parameter, field or method return value can be null. + *

+ * When decorating a method call parameter, this denotes that the parameter can + * legitimately be null and the method will gracefully deal with it. Typically + * used on optional parameters. + *

+ * When decorating a method, this denotes the method might legitimately return + * null. + *

+ * This is a marker annotation and it has no specific attributes. + * + * @paramDoc This value may be {@code null}. + * @returnDoc This value may be {@code null}. + */ +@Retention(SOURCE) +@Target({METHOD, PARAMETER, FIELD}) +public @interface Nullable { +} diff --git a/hiddenapi/stubs/src/main/java/android/content/Intent.java b/hiddenapi/stubs/src/main/java/android/content/Intent.java new file mode 100644 index 00000000..48c55e8f --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/Intent.java @@ -0,0 +1,23 @@ +/* + * This file is part of LSPosed. + * + * LSPosed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LSPosed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LSPosed. If not, see . + * + * Copyright (C) 2021 LSPosed Contributors + */ + +package android.content; + +public class Intent { +} diff --git a/hiddenapi/stubs/src/main/java/android/content/IntentSender.java b/hiddenapi/stubs/src/main/java/android/content/IntentSender.java new file mode 100644 index 00000000..1279e06d --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/IntentSender.java @@ -0,0 +1,4 @@ +package android.content; + +public class IntentSender { +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/ApplicationInfo.java b/hiddenapi/stubs/src/main/java/android/content/pm/ApplicationInfo.java new file mode 100644 index 00000000..a6e62a6c --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/pm/ApplicationInfo.java @@ -0,0 +1,12 @@ +package android.content.pm; + +import androidx.annotation.RequiresApi; + +public class ApplicationInfo { + public String credentialProtectedDataDir; + + public String[] resourceDirs; + + @RequiresApi(31) + public String[] overlayPaths; +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/BaseParceledListSlice.java b/hiddenapi/stubs/src/main/java/android/content/pm/BaseParceledListSlice.java new file mode 100644 index 00000000..d9af8b52 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/pm/BaseParceledListSlice.java @@ -0,0 +1,10 @@ +package android.content.pm; + +import java.util.List; + +abstract class BaseParceledListSlice { + + public List getList() { + throw new RuntimeException("STUB"); + } +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/IPackageInstaller.java b/hiddenapi/stubs/src/main/java/android/content/pm/IPackageInstaller.java new file mode 100644 index 00000000..c77a0134 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/pm/IPackageInstaller.java @@ -0,0 +1,16 @@ +package android.content.pm; + +import android.os.Binder; +import android.os.IBinder; +import android.os.IInterface; + +public interface IPackageInstaller extends IInterface { + + void uninstall(android.content.pm.VersionedPackage versionedPackage, java.lang.String callerPackageName, int flags, android.content.IntentSender statusReceiver, int userId) throws android.os.RemoteException; + + abstract class Stub extends Binder implements IPackageInstaller { + public static IPackageInstaller asInterface(IBinder obj) { + throw new UnsupportedOperationException(); + } + } +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/IPackageManager.java b/hiddenapi/stubs/src/main/java/android/content/pm/IPackageManager.java new file mode 100644 index 00000000..279e8975 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/pm/IPackageManager.java @@ -0,0 +1,104 @@ +package android.content.pm; + +import android.content.Intent; +import android.os.Binder; +import android.os.IBinder; +import android.os.IInterface; +import android.os.RemoteException; + +import androidx.annotation.RequiresApi; + +import java.util.List; + +public interface IPackageManager extends IInterface { + + boolean isPackageAvailable(String packageName, int userId) throws RemoteException; + + boolean getApplicationHiddenSettingAsUser(String packageName, int userId) throws RemoteException; + + ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) + throws RemoteException; + + @RequiresApi(33) + ApplicationInfo getApplicationInfo(String packageName, long flags, int userId) + throws RemoteException; + + PackageInfo getPackageInfo(String packageName, int flags, int userId) + throws RemoteException; + + @RequiresApi(33) + PackageInfo getPackageInfo(String packageName, long flags, int userId) + throws RemoteException; + + int getPackageUid(String packageName, int flags, int userId) throws RemoteException; + + @RequiresApi(33) + int getPackageUid(String packageName, long flags, int userId) throws RemoteException; + + String[] getPackagesForUid(int uid) + throws RemoteException; + + ParceledListSlice getInstalledPackages(int flags, int userId) + throws RemoteException; + + @RequiresApi(33) + ParceledListSlice getInstalledPackages(long flags, int userId) + throws RemoteException; + + ParceledListSlice getInstalledApplications(int flags, int userId) + throws RemoteException; + + @RequiresApi(33) + ParceledListSlice getInstalledApplications(long flags, int userId) + throws RemoteException; + + int getUidForSharedUser(String sharedUserName) + throws RemoteException; + + void grantRuntimePermission(String packageName, String permissionName, int userId) + throws RemoteException; + + void revokeRuntimePermission(String packageName, String permissionName, int userId) + throws RemoteException; + + int getPermissionFlags(String permissionName, String packageName, int userId) + throws RemoteException; + + void updatePermissionFlags(String permissionName, String packageName, int flagMask, int flagValues, int userId) + throws RemoteException; + + int checkPermission(String permName, String pkgName, int userId) + throws RemoteException; + + int checkUidPermission(String permName, int uid) + throws RemoteException; + + IPackageInstaller getPackageInstaller() throws RemoteException; + + int installExistingPackageAsUser(String packageName, int userId, int installFlags, + int installReason) throws RemoteException; + + @RequiresApi(29) + int installExistingPackageAsUser(String packageName, int userId, int installFlags, + int installReason, List whiteListedPermissions) throws RemoteException; + + ParceledListSlice queryIntentActivities(Intent intent, + String resolvedType, int flags, int userId) throws RemoteException; + + @RequiresApi(33) + ParceledListSlice queryIntentActivities(Intent intent, + String resolvedType, long flags, int userId) throws RemoteException; + + boolean performDexOptMode(String packageName, boolean checkProfiles, + String targetCompilerFilter, boolean force, boolean bootComplete, String splitName) + throws RemoteException; + + void clearApplicationProfileData(String packageName) throws RemoteException; + + abstract class Stub extends Binder implements IPackageManager { + + public static IPackageManager asInterface(IBinder obj) { + throw new UnsupportedOperationException(); + } + } +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/PackageInfo.java b/hiddenapi/stubs/src/main/java/android/content/pm/PackageInfo.java new file mode 100644 index 00000000..f087c27c --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/pm/PackageInfo.java @@ -0,0 +1,6 @@ +package android.content.pm; + +public class PackageInfo { + + public String overlayTarget; +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/ParceledListSlice.java b/hiddenapi/stubs/src/main/java/android/content/pm/ParceledListSlice.java new file mode 100644 index 00000000..6b98d7bd --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/pm/ParceledListSlice.java @@ -0,0 +1,10 @@ +package android.content.pm; + +import java.util.List; + +public class ParceledListSlice extends BaseParceledListSlice { + public ParceledListSlice(List list) { + throw new IllegalArgumentException("STUB"); + } + +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/ResolveInfo.java b/hiddenapi/stubs/src/main/java/android/content/pm/ResolveInfo.java new file mode 100644 index 00000000..e00de135 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/pm/ResolveInfo.java @@ -0,0 +1,4 @@ +package android.content.pm; + +public class ResolveInfo { +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/UserInfo.java b/hiddenapi/stubs/src/main/java/android/content/pm/UserInfo.java new file mode 100644 index 00000000..2e73eec6 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/pm/UserInfo.java @@ -0,0 +1,6 @@ +package android.content.pm; + +public class UserInfo { + public int id; + public String name; +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/VersionedPackage.java b/hiddenapi/stubs/src/main/java/android/content/pm/VersionedPackage.java new file mode 100644 index 00000000..0d1bf99d --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/content/pm/VersionedPackage.java @@ -0,0 +1,4 @@ +package android.content.pm; + +public class VersionedPackage { +} diff --git a/hiddenapi/stubs/src/main/java/android/os/Binder.java b/hiddenapi/stubs/src/main/java/android/os/Binder.java new file mode 100644 index 00000000..967f0c5c --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/os/Binder.java @@ -0,0 +1,62 @@ +package android.os; + +import android.annotation.NonNull; +import android.annotation.Nullable; + +import java.io.FileDescriptor; + +public class Binder implements IBinder { + + @Override + public boolean transact(int code, @NonNull Parcel data, Parcel reply, int flags) { + throw new RuntimeException("STUB"); + } + + @Override + public String getInterfaceDescriptor() { + throw new RuntimeException("STUB"); + } + + public boolean pingBinder() { + throw new RuntimeException("STUB"); + } + + @Override + public boolean isBinderAlive() { + throw new RuntimeException("STUB"); + } + + @Override + public IInterface queryLocalInterface(@NonNull String descriptor) { + throw new RuntimeException("STUB"); + } + + @Override + public void dump(@NonNull FileDescriptor fd, String[] args) { + throw new RuntimeException("STUB"); + } + + @Override + public void dumpAsync(@NonNull FileDescriptor fd, String[] args) { + throw new RuntimeException("STUB"); + } + + @Override + public void linkToDeath(@NonNull DeathRecipient recipient, int flags) { + throw new RuntimeException("STUB"); + } + + @Override + public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) { + throw new RuntimeException("STUB"); + } + + protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, + int flags) throws RemoteException { + throw new RuntimeException("STUB"); + } + + public static IBinder allowBlocking(IBinder binder){ + throw new RuntimeException("STUB"); + } +} diff --git a/hiddenapi/stubs/src/main/java/android/os/IBinder.java b/hiddenapi/stubs/src/main/java/android/os/IBinder.java new file mode 100644 index 00000000..81ad36c9 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/os/IBinder.java @@ -0,0 +1,33 @@ +package android.os; + +import android.annotation.NonNull; +import android.annotation.Nullable; + +import java.io.FileDescriptor; + +public interface IBinder { + + boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags); + + @Nullable + String getInterfaceDescriptor(); + + boolean pingBinder(); + + boolean isBinderAlive(); + + @Nullable + IInterface queryLocalInterface(@NonNull String descriptor); + + void dump(@NonNull FileDescriptor fd, @Nullable String[] args); + + void dumpAsync(@NonNull FileDescriptor fd, @Nullable String[] args); + + void linkToDeath(@NonNull DeathRecipient recipient, int flags); + + boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags); + + interface DeathRecipient { + void binderDied(); + } +} diff --git a/hiddenapi/stubs/src/main/java/android/os/IInterface.java b/hiddenapi/stubs/src/main/java/android/os/IInterface.java new file mode 100644 index 00000000..997e330f --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/os/IInterface.java @@ -0,0 +1,6 @@ +package android.os; + +public interface IInterface { + + IBinder asBinder(); +} diff --git a/hiddenapi/stubs/src/main/java/android/os/Parcel.java b/hiddenapi/stubs/src/main/java/android/os/Parcel.java new file mode 100644 index 00000000..f506a638 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/os/Parcel.java @@ -0,0 +1,4 @@ +package android.os; + +public class Parcel { +} diff --git a/hiddenapi/stubs/src/main/java/android/os/RemoteException.java b/hiddenapi/stubs/src/main/java/android/os/RemoteException.java new file mode 100644 index 00000000..9b24d72b --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/os/RemoteException.java @@ -0,0 +1,8 @@ +package android.os; + +public class RemoteException extends Exception { + + public RemoteException(String message) { + throw new RuntimeException("STUB"); + } +} diff --git a/hiddenapi/stubs/src/main/java/android/os/ServiceManager.java b/hiddenapi/stubs/src/main/java/android/os/ServiceManager.java new file mode 100644 index 00000000..bf1a9f21 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/android/os/ServiceManager.java @@ -0,0 +1,28 @@ +package android.os; + +import android.annotation.Nullable; + +public class ServiceManager { + + /** + * Returns a reference to a service with the given name. + * + * @param name the name of the service to get + * @return a reference to the service, or null if the service doesn't exist + */ + @Nullable + public static IBinder getService(String name) { + throw new RuntimeException("STUB"); + } + + /** + * Place a new @a service called @a name into the service + * manager. + * + * @param name the name of the new service + * @param service the service object + */ + public static void addService(String name, IBinder service) { + throw new RuntimeException("STUB"); + } +} diff --git a/hiddenapi/stubs/src/main/java/androidx/annotation/IntRange.java b/hiddenapi/stubs/src/main/java/androidx/annotation/IntRange.java new file mode 100644 index 00000000..80691fd3 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/androidx/annotation/IntRange.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.LOCAL_VARIABLE; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.CLASS; + +/** + * Denotes that the annotated element should be an int or long in the given range + *

+ * Example: + *


+ *  @IntRange(from=0,to=255)
+ *  public int getAlpha() {
+ *      ...
+ *  }
+ * 
+ */ +@Retention(CLASS) +@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE, ANNOTATION_TYPE}) +public @interface IntRange { + /** + * Smallest value, inclusive + */ + long from() default Long.MIN_VALUE; + + /** + * Largest value, inclusive + */ + long to() default Long.MAX_VALUE; +} \ No newline at end of file diff --git a/hiddenapi/stubs/src/main/java/androidx/annotation/RequiresApi.java b/hiddenapi/stubs/src/main/java/androidx/annotation/RequiresApi.java new file mode 100644 index 00000000..cb1d4624 --- /dev/null +++ b/hiddenapi/stubs/src/main/java/androidx/annotation/RequiresApi.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +/** + * Denotes that the annotated element should only be called on the given API level + * or higher. + *

+ * This is similar in purpose to the older {@code @TargetApi} annotation, but more + * clearly expresses that this is a requirement on the caller, rather than being + * used to "suppress" warnings within the method that exceed the {@code minSdkVersion}. + */ +@Retention(SOURCE) +@Target({TYPE, METHOD, CONSTRUCTOR, FIELD}) +public @interface RequiresApi { + + /** + * The API level to require. Alias for {@link #api} which allows you to leave out the + * {@code api=} part. + */ + @IntRange(from = 1) + int value() default 1; + + /** + * The API level to require + */ + @IntRange(from = 1) + int api() default 1; +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index e7b4def4..2ce1c6d2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,2 @@ include ':app' +include ':hiddenapi:stubs'