diff --git a/app/build.gradle b/app/build.gradle index 19deab7cf..ea1abdd01 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,5 +33,4 @@ dependencies { implementation 'eu.chainfire:libsuperuser:1.0.0.201608240809' implementation 'com.squareup.picasso:picasso:2.5.2' implementation 'de.psdev.licensesdialog:licensesdialog:1.8.1' - compileOnly fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/app/libs/AndroidHiddenAPI.jar b/app/libs/AndroidHiddenAPI.jar deleted file mode 100644 index 113acc1e3..000000000 Binary files a/app/libs/AndroidHiddenAPI.jar and /dev/null differ diff --git a/app/src/main/java/de/robv/android/xposed/installer/XposedApp.java b/app/src/main/java/de/robv/android/xposed/installer/XposedApp.java index abb821164..1fe78c128 100644 --- a/app/src/main/java/de/robv/android/xposed/installer/XposedApp.java +++ b/app/src/main/java/de/robv/android/xposed/installer/XposedApp.java @@ -11,7 +11,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; -import android.os.FileUtils; import android.os.Handler; import android.preference.PreferenceManager; import android.support.v4.content.FileProvider; @@ -20,10 +19,10 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.lang.reflect.Method; import de.robv.android.xposed.installer.util.AssetUtil; import de.robv.android.xposed.installer.util.DownloadsUtil; +import de.robv.android.xposed.installer.util.FileUtil; import de.robv.android.xposed.installer.util.InstallZipUtil; import de.robv.android.xposed.installer.util.InstallZipUtil.XposedProp; import de.robv.android.xposed.installer.util.NotificationUtil; @@ -124,26 +123,21 @@ public void onCreate() { } private void createDirectories() { - FileUtils.setPermissions(BASE_DIR, 00711, -1, -1); - mkdirAndChmod("conf", 00771); - mkdirAndChmod("log", 00777); + FileUtil.setPermissions(BASE_DIR, 7, 1); + mkdirAndChmod("conf", 7, 1); + mkdirAndChmod("log", 7, 7); if (Build.VERSION.SDK_INT >= 24) { - try { - Method deleteDir = FileUtils.class.getDeclaredMethod("deleteContentsAndDir", File.class); - deleteDir.invoke(null, new File(BASE_DIR_LEGACY, "bin")); - deleteDir.invoke(null, new File(BASE_DIR_LEGACY, "conf")); - deleteDir.invoke(null, new File(BASE_DIR_LEGACY, "log")); - } catch (ReflectiveOperationException e) { - Log.w(XposedApp.TAG, "Failed to delete obsolete directories", e); - } + FileUtil.deleteContentsAndDir(new File(BASE_DIR_LEGACY, "bin")); + FileUtil.deleteContentsAndDir(new File(BASE_DIR_LEGACY, "conf")); + FileUtil.deleteContentsAndDir(new File(BASE_DIR_LEGACY, "log")); } } - private void mkdirAndChmod(String dir, int permissions) { - dir = BASE_DIR + dir; - new File(dir).mkdir(); - FileUtils.setPermissions(dir, permissions, -1, -1); + private void mkdirAndChmod(String name, int owner, int other) { + File dir = new File(BASE_DIR + name); + dir.mkdir(); + FileUtil.setPermissions(dir, owner, other); } public void reloadXposedProp() { diff --git a/app/src/main/java/de/robv/android/xposed/installer/installation/FlashDirectly.java b/app/src/main/java/de/robv/android/xposed/installer/installation/FlashDirectly.java index e230d3fd7..fad7f66d8 100644 --- a/app/src/main/java/de/robv/android/xposed/installer/installation/FlashDirectly.java +++ b/app/src/main/java/de/robv/android/xposed/installer/installation/FlashDirectly.java @@ -46,7 +46,7 @@ public void flash(Context context, FlashCallback callback) { ZipEntry entry = zip.getEntry("META-INF/com/google/android/update-binary"); File updateBinaryFile = new File(XposedApp.getInstance().getCacheDir(), "update-binary"); try { - AssetUtil.writeStreamToFile(zip.getInputStream(entry), updateBinaryFile, 0700); + AssetUtil.writeStreamToFile(zip.getInputStream(entry), updateBinaryFile, 7, 0); } catch (IOException e) { Log.e(XposedApp.TAG, "Could not extract update-binary", e); triggerError(callback, FlashCallback.ERROR_INVALID_ZIP); diff --git a/app/src/main/java/de/robv/android/xposed/installer/util/AssetUtil.java b/app/src/main/java/de/robv/android/xposed/installer/util/AssetUtil.java index 63b2bc826..5b71de532 100644 --- a/app/src/main/java/de/robv/android/xposed/installer/util/AssetUtil.java +++ b/app/src/main/java/de/robv/android/xposed/installer/util/AssetUtil.java @@ -2,7 +2,6 @@ import android.content.res.AssetManager; import android.os.Build; -import android.os.FileUtils; import android.util.Log; import java.io.File; @@ -26,12 +25,13 @@ public static String getBinariesFolder() { } } - public static File writeAssetToFile(AssetManager assets, String assetName, File targetFile, int mode) { + public static File writeAssetToFile(AssetManager assets, String assetName, + File targetFile, int owner, int other) { try { if (assets == null) assets = XposedApp.getInstance().getAssets(); InputStream in = assets.open(assetName); - writeStreamToFile(in, targetFile, mode);; + writeStreamToFile(in, targetFile, owner, other); return targetFile; } catch (IOException e) { Log.e(XposedApp.TAG, "could not extract asset", e); @@ -42,7 +42,8 @@ public static File writeAssetToFile(AssetManager assets, String assetName, File } } - public static void writeStreamToFile(InputStream in, File targetFile, int mode) throws IOException { + public static void writeStreamToFile(InputStream in, File targetFile, + int owner, int other) throws IOException { FileOutputStream out = new FileOutputStream(targetFile); byte[] buffer = new byte[1024]; @@ -53,7 +54,7 @@ public static void writeStreamToFile(InputStream in, File targetFile, int mode) in.close(); out.close(); - FileUtils.setPermissions(targetFile.getAbsolutePath(), mode, -1, -1); + FileUtil.setPermissions(targetFile.getAbsolutePath(), owner, other); } public synchronized static void extractBusybox() { @@ -61,7 +62,7 @@ public synchronized static void extractBusybox() { return; AssetManager assets = null; - writeAssetToFile(assets, getBinariesFolder() + "busybox-xposed", BUSYBOX_FILE, 00700); + writeAssetToFile(assets, getBinariesFolder() + "busybox-xposed", BUSYBOX_FILE, 7, 0); } public synchronized static void removeBusybox() { diff --git a/app/src/main/java/de/robv/android/xposed/installer/util/FileUtil.java b/app/src/main/java/de/robv/android/xposed/installer/util/FileUtil.java new file mode 100644 index 000000000..aacb87f32 --- /dev/null +++ b/app/src/main/java/de/robv/android/xposed/installer/util/FileUtil.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2006 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 de.robv.android.xposed.installer.util; + +import android.util.Log; + +import java.io.File; + +import de.robv.android.xposed.installer.XposedApp; + +public class FileUtil { + public static boolean setPermissions(String path, int owner, int other) { + return setPermissions(new File(path), owner, other); + } + + public static boolean setPermissions(File path, int owner, int other) { + if (!setPermissions(path, other, false) || !setPermissions(path, owner, true)) { + Log.w(XposedApp.TAG, "Failed to set permissions " + + owner + "/" + other + " for " + path.getPath()); + return false; + } + return true; + } + + private static boolean setPermissions(File path, int perm, boolean ownerOnly) { + return path.setReadable((perm & 4) != 0, ownerOnly) + && path.setWritable((perm & 2) != 0, ownerOnly) + && path.setExecutable((perm & 1) != 0, ownerOnly); + } + + public static boolean deleteContentsAndDir(File dir) { + if (deleteContents(dir)) { + return dir.delete(); + } else { + return false; + } + } + + public static boolean deleteContents(File dir) { + File[] files = dir.listFiles(); + boolean success = true; + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + success &= deleteContents(file); + } + if (!file.delete()) { + Log.w(XposedApp.TAG, "Failed to delete " + file); + success = false; + } + } + } + return success; + } +} diff --git a/app/src/main/java/de/robv/android/xposed/installer/util/ModuleUtil.java b/app/src/main/java/de/robv/android/xposed/installer/util/ModuleUtil.java index 9aa8e1de3..e38788b7c 100644 --- a/app/src/main/java/de/robv/android/xposed/installer/util/ModuleUtil.java +++ b/app/src/main/java/de/robv/android/xposed/installer/util/ModuleUtil.java @@ -9,7 +9,6 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; -import android.os.FileUtils; import android.util.Log; import android.widget.Toast; @@ -223,8 +222,8 @@ public synchronized void updateModulesList(boolean showToast) { modulesList.close(); enabledModulesList.close(); - FileUtils.setPermissions(MODULES_LIST_FILE, 00664, -1, -1); - FileUtils.setPermissions(XposedApp.ENABLED_MODULES_LIST_FILE, 00664, -1, -1); + FileUtil.setPermissions(MODULES_LIST_FILE, 6, 4); + FileUtil.setPermissions(XposedApp.ENABLED_MODULES_LIST_FILE, 6, 4); if (showToast) showToast(R.string.xposed_module_list_updated);